mirror of
https://github.com/devfake/flox.git
synced 2024-11-14 22:22:39 +01:00
improve last seen filter (#56)
* prepare migrations and relation * update and order by new last_seen_at field * add tests * update production files
This commit is contained in:
parent
cb119e2ff4
commit
ec2f87daef
@ -2,13 +2,10 @@
|
||||
|
||||
namespace App;
|
||||
|
||||
use App\Services\TMDB;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Episode extends Model {
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'tmdb_id',
|
||||
'name',
|
||||
@ -18,8 +15,9 @@
|
||||
'episode_tmdb_id',
|
||||
'seen',
|
||||
'season_tmdb_id',
|
||||
'created_at',
|
||||
'subtitles',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -39,12 +37,20 @@
|
||||
'episode_number' => $episode->episode_number,
|
||||
'name' => $episode->name,
|
||||
'tmdb_id' => $tmdbId,
|
||||
'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Relations
|
||||
*/
|
||||
|
||||
public function item()
|
||||
{
|
||||
return $this->belongsTo(Item::class, 'tmdb_id', 'tmdb_id');
|
||||
}
|
||||
|
||||
/*
|
||||
* Scopes
|
||||
*/
|
||||
|
@ -33,10 +33,11 @@
|
||||
/**
|
||||
* Return all items with pagination.
|
||||
*
|
||||
* @param ItemService $item
|
||||
* @param ItemService $itemService
|
||||
* @param $type
|
||||
* @param $orderBy
|
||||
* @return mixed
|
||||
* @internal param ItemService $item
|
||||
*/
|
||||
public function items(ItemService $itemService, $type, $orderBy)
|
||||
{
|
||||
@ -138,6 +139,8 @@
|
||||
|
||||
/**
|
||||
* Toggle all episodes of an season as seen / unseen.
|
||||
*
|
||||
* @param EpisodeService $episode
|
||||
*/
|
||||
public function toggleSeason(EpisodeService $episode)
|
||||
{
|
||||
|
@ -9,6 +9,7 @@
|
||||
use App\Services\Storage;
|
||||
use App\Services\TMDB;
|
||||
use App\Setting;
|
||||
use Carbon\Carbon;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\ConnectException;
|
||||
use Illuminate\Contracts\Routing\ResponseFactory;
|
||||
@ -79,6 +80,11 @@
|
||||
if(isset($data->items)) {
|
||||
$this->item->truncate();
|
||||
foreach($data->items as $item) {
|
||||
// Fallback if export was from an older version of flox.
|
||||
if( ! isset($item->last_seen_at)) {
|
||||
$item->last_seen_at = Carbon::createFromTimestamp($item->created_at);
|
||||
}
|
||||
|
||||
$this->item->create((array) $item);
|
||||
$this->storage->downloadPoster($item->poster);
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
namespace App;
|
||||
|
||||
use App\Services\Storage;
|
||||
use App\Services\TMDB;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Laravel\Scout\Searchable;
|
||||
|
||||
@ -12,7 +11,7 @@
|
||||
// Uncomment this if you are using Laravel Scout.
|
||||
//use Searchable;
|
||||
|
||||
public $timestamps = false;
|
||||
protected $dates = ['last_seen'];
|
||||
|
||||
protected $fillable = [
|
||||
'tmdb_id',
|
||||
@ -22,11 +21,13 @@
|
||||
'media_type',
|
||||
'rating',
|
||||
'released',
|
||||
'created_at',
|
||||
'genre',
|
||||
'fp_name',
|
||||
'src',
|
||||
'subtitles',
|
||||
'last_seen_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -46,7 +47,7 @@
|
||||
'rating' => 0,
|
||||
'released' => $data['released'],
|
||||
'genre' => $data['genre'],
|
||||
'created_at' => time(),
|
||||
'last_seen_at' => Carbon::now(),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -65,9 +66,20 @@
|
||||
'poster' => '',
|
||||
'rating' => 1,
|
||||
'released' => time(),
|
||||
'created_at' => time(),
|
||||
'src' => $data['src'],
|
||||
'subtitles' => $data['subtitles'],
|
||||
'last_seen_at' => Carbon::now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tmdbId
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateLastSeenAt($tmdbId)
|
||||
{
|
||||
return $this->where('tmdb_id', $tmdbId)->update([
|
||||
'last_seen_at' => Carbon::now(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Services\Models;
|
||||
|
||||
use App\Episode as Model;
|
||||
use App\Item;
|
||||
use App\Services\TMDB;
|
||||
use App\Setting;
|
||||
|
||||
@ -10,15 +11,22 @@
|
||||
|
||||
private $model;
|
||||
private $tmdb;
|
||||
private $item;
|
||||
|
||||
/**
|
||||
* @param Model $model
|
||||
* @param TMDB $tmdb
|
||||
* @param Item $item
|
||||
*
|
||||
* @internal param ItemService $itemService
|
||||
*
|
||||
* @internal param Item $item
|
||||
*/
|
||||
public function __construct(Model $model, TMDB $tmdb)
|
||||
public function __construct(Model $model, TMDB $tmdb, Item $item)
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->tmdb = $tmdb;
|
||||
$this->item = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,6 +79,11 @@
|
||||
$episode = $this->model->find($id);
|
||||
|
||||
if($episode) {
|
||||
// Update the parent relation only if we mark the episode as seen.
|
||||
if( ! $episode->seen) {
|
||||
$this->item->updateLastSeenAt($episode->tmdb_id);
|
||||
}
|
||||
|
||||
return $episode->update([
|
||||
'seen' => ! $episode->seen,
|
||||
]);
|
||||
@ -86,6 +99,11 @@
|
||||
{
|
||||
$episodes = $this->model->findSeason($tmdbId, $season)->get();
|
||||
|
||||
// Update the parent relation only if we mark the episode as seen.
|
||||
if($seen) {
|
||||
$this->item->updateLastSeenAt($episodes[0]->tmdb_id);
|
||||
}
|
||||
|
||||
$episodes->each(function($episode) use ($seen) {
|
||||
$episode->update([
|
||||
'seen' => $seen,
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
$factory->define(App\User::class, function(Faker\Generator $faker) {
|
||||
static $password;
|
||||
|
||||
@ -25,7 +27,7 @@
|
||||
'rating' => 1,
|
||||
'genre' => '',
|
||||
'released' => time(),
|
||||
'created_at' => time(),
|
||||
'last_seen_at' => Carbon::now(),
|
||||
'src' => null,
|
||||
];
|
||||
});
|
||||
@ -35,7 +37,6 @@
|
||||
'name' => $faker->name,
|
||||
'season_tmdb_id' => 1,
|
||||
'episode_tmdb_id' => 1,
|
||||
'created_at' => time(),
|
||||
'src' => null,
|
||||
];
|
||||
});
|
||||
|
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddTimestampsToEpisodes extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::table('episodes', function (Blueprint $table) {
|
||||
$table->dropColumn('created_at');
|
||||
});
|
||||
|
||||
Schema::table('episodes', function (Blueprint $table) {
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('episodes', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
use App\Item;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddTimestampsAndLastSeenAtToItems extends Migration {
|
||||
|
||||
private $items;
|
||||
|
||||
public function up()
|
||||
{
|
||||
$this->items = Item::get(['id', 'created_at']);
|
||||
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn('created_at');
|
||||
});
|
||||
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->timestamps();
|
||||
$table->timestamp('last_seen_at')->nullable();
|
||||
});
|
||||
|
||||
$this->repopulateCreatedAt();
|
||||
}
|
||||
|
||||
/**
|
||||
* We can't change an integer field to a timestamp field.
|
||||
* So we need to remove the current created_at integer field,
|
||||
* create the new timestamp fields, and repopulate the old created_at data.
|
||||
*/
|
||||
private function repopulateCreatedAt()
|
||||
{
|
||||
$this->items->map(function ($item) {
|
||||
$item->created_at = $item->created_at;
|
||||
$item->updated_at = $item->created_at;
|
||||
$item->last_seen_at = $item->created_at;
|
||||
$item->save();
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use App\Episode;
|
||||
use App\Item;
|
||||
use App\Services\Models\EpisodeService;
|
||||
use App\Services\Models\ItemService;
|
||||
use App\Services\TMDB;
|
||||
@ -11,12 +12,16 @@
|
||||
use DatabaseMigrations;
|
||||
|
||||
private $episode;
|
||||
private $episodeService;
|
||||
private $item;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->episode = app(Episode::class);
|
||||
$this->episodeService = app(EpisodeService::class);
|
||||
$this->item = app(Item::class);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
@ -39,12 +44,11 @@
|
||||
public function it_should_set_a_episode_as_seen_or_unseen()
|
||||
{
|
||||
$this->createTv();
|
||||
$episodeService = app(EpisodeService::class);
|
||||
|
||||
$episode1 = $this->episode->find(1);
|
||||
$episodeService->toggleSeen(1);
|
||||
$this->episodeService->toggleSeen(1);
|
||||
$episode2 = $this->episode->find(1);
|
||||
$episodeService->toggleSeen(1);
|
||||
$this->episodeService->toggleSeen(1);
|
||||
$episode3 = $this->episode->find(1);
|
||||
|
||||
$this->assertEquals(0, $episode1->seen);
|
||||
@ -56,15 +60,14 @@
|
||||
public function it_should_set_all_episodes_of_a_season_as_seen_or_unseen()
|
||||
{
|
||||
$this->createTv();
|
||||
$episodeService = app(EpisodeService::class);
|
||||
|
||||
$season = 1;
|
||||
$tmdbId = 1399;
|
||||
|
||||
$episodes1 = $this->episode->where('season_number', $season)->get();
|
||||
$episodeService->toggleSeason($tmdbId, 1, 1);
|
||||
$this->episodeService->toggleSeason($tmdbId, $season, 1);
|
||||
$episodes2 = $this->episode->where('season_number', $season)->get();
|
||||
$episodeService->toggleSeason($tmdbId, 1, 0);
|
||||
$this->episodeService->toggleSeason($tmdbId, $season, 0);
|
||||
$episodes3 = $this->episode->where('season_number', $season)->get();
|
||||
|
||||
$episodes1->each(function($episode) {
|
||||
@ -82,16 +85,68 @@
|
||||
public function it_should_remove_episodes()
|
||||
{
|
||||
$this->createTv();
|
||||
$episodeService = app(EpisodeService::class);
|
||||
|
||||
$episodes1 = $this->episode->findByTmdbId(1399)->get();
|
||||
$episodeService->remove(1399);
|
||||
$this->episodeService->remove(1399);
|
||||
$episodes2 = $this->episode->findByTmdbId(1399)->get();
|
||||
|
||||
$this->assertNotNull($episodes1);
|
||||
$this->assertCount(0, $episodes2);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_should_update_items_from_one_episode()
|
||||
{
|
||||
$this->createTv();
|
||||
|
||||
$item = $this->item->find(1);
|
||||
sleep(1);
|
||||
$this->episodeService->toggleSeen(1);
|
||||
$itemUpdated = $this->item->find(1);
|
||||
|
||||
$this->assertNotEquals($itemUpdated->last_seen_at, $item->last_seen_at);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_should_update_items_only_on_seen_from_one_episode()
|
||||
{
|
||||
$this->createTv();
|
||||
|
||||
$this->episodeService->toggleSeen(1);
|
||||
$item = $this->item->find(1);
|
||||
sleep(1);
|
||||
$this->episodeService->toggleSeen(1);
|
||||
$itemUpdated = $this->item->find(1);
|
||||
|
||||
$this->assertEquals($itemUpdated->last_seen_at, $item->last_seen_at);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_should_update_items_from_all_episodes()
|
||||
{
|
||||
$this->createTv();
|
||||
|
||||
$item = $this->item->find(1);
|
||||
sleep(1);
|
||||
$this->episodeService->toggleSeason(1399, 1, 1);
|
||||
$itemUpdated = $this->item->find(1);
|
||||
|
||||
$this->assertNotEquals($itemUpdated->last_seen_at, $item->last_seen_at);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_should_update_items_only_on_seen_from_all_episodes()
|
||||
{
|
||||
$this->createTv();
|
||||
|
||||
$item = $this->item->find(1);
|
||||
sleep(1);
|
||||
$this->episodeService->toggleSeason(1399, 1, 0);
|
||||
$itemUpdated = $this->item->find(1);
|
||||
|
||||
$this->assertEquals($itemUpdated->last_seen_at, $item->last_seen_at);
|
||||
}
|
||||
|
||||
private function createTmdbMock()
|
||||
{
|
||||
// Mock this to avoid unknown requests to TMDb (get seasons and then get episodes for each season)
|
||||
|
@ -6,7 +6,7 @@
|
||||
</router-link>
|
||||
|
||||
<span class="sort-wrap">
|
||||
<i :title="lang('last seen')" class="icon-sort-time" :class="{active: userFilter == 'created_at'}" @click="setUserFilter('created_at')"></i>
|
||||
<i :title="lang('last seen')" class="icon-sort-time" :class="{active: userFilter == 'last_seen_at'}" @click="setUserFilter('last_seen_at')"></i>
|
||||
<i :title="lang('best rated')" class="icon-sort-star" :class="{active: userFilter == 'rating'}" @click="setUserFilter('rating')"></i>
|
||||
<span :title="lang('change color')" class="icon-constrast" @click="toggleColorScheme()"><i></i></span>
|
||||
</span>
|
||||
@ -59,7 +59,7 @@
|
||||
|
||||
checkForUserFilter() {
|
||||
if( ! localStorage.getItem('filter')) {
|
||||
localStorage.setItem('filter', 'created_at');
|
||||
localStorage.setItem('filter', 'last_seen_at');
|
||||
}
|
||||
|
||||
this.SET_USER_FILTER(localStorage.getItem('filter'));
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user