diff --git a/src/frontend/src/app/torrent-details/torrent-details.component.html b/src/frontend/src/app/torrent-details/torrent-details.component.html index 108c0a58..59d1d846 100644 --- a/src/frontend/src/app/torrent-details/torrent-details.component.html +++ b/src/frontend/src/app/torrent-details/torrent-details.component.html @@ -23,9 +23,17 @@ {{ result.watchMedia.release_date | date | date: 'shortDate' }} {{ result.watchMedia.date_added | date | date: 'shortDate' }} + - {{ result.watchMedia.last_attempt_date | amTimeAgo }} - working on it... + + + Media hasn't been released yet + + + + {{ result.watchMedia.last_attempt_date | amTimeAgo }} + working on it... + {{ result.watchMedia.collected_date | date | date: 'shortDate' }} diff --git a/src/frontend/src/app/torrent-details/torrent-details.component.ts b/src/frontend/src/app/torrent-details/torrent-details.component.ts index 391a8f3a..e0a57e0c 100644 --- a/src/frontend/src/app/torrent-details/torrent-details.component.ts +++ b/src/frontend/src/app/torrent-details/torrent-details.component.ts @@ -1,8 +1,9 @@ -import { Component, OnInit, Input, OnDestroy } from '@angular/core'; -import { ApiService } from '../api.service'; -import { ToastrService } from 'ngx-toastr'; -import { interval, Observable } from 'rxjs'; -import { throttle } from 'rxjs/operators'; +import {Component, OnInit, Input, OnDestroy} from '@angular/core'; +import {ApiService} from '../api.service'; +import {ToastrService} from 'ngx-toastr'; +import {interval, Observable} from 'rxjs'; +import {throttle} from 'rxjs/operators'; +import * as moment from 'moment'; const POLL_TIME = 5000; @@ -27,7 +28,8 @@ export class TorrentDetailsComponent implements OnInit, OnDestroy { constructor( private apiService: ApiService, private toastr: ToastrService, - ) {} + ) { + } ngOnDestroy() { // stop polling for torrent details @@ -101,6 +103,12 @@ export class TorrentDetailsComponent implements OnInit, OnDestroy { return result.watchMedia.id; } + public isReleaseInFuture(media: any): boolean { + const now = moment().format(); + const releaseDate = moment(media.release_date || 'x'); + return releaseDate.isValid() && releaseDate.isAfter(now, 'day'); + } + protected _fetchTorrents(): Observable { this.isFetchingInitialTorrents = false; diff --git a/src/nefarious/processors.py b/src/nefarious/processors.py index 9141e5c2..ac820fa9 100644 --- a/src/nefarious/processors.py +++ b/src/nefarious/processors.py @@ -1,5 +1,6 @@ import os import regex +from typing import Union from django.apps import apps from django.conf import settings from datetime import datetime @@ -18,7 +19,7 @@ class WatchProcessorBase: - watch_media = None + watch_media: Union[WatchMovie, WatchTVEpisode, WatchTVSeason] = None nefarious_settings: NefariousSettings = None _reprocess_without_possessive_apostrophes = False _possessive_apostrophes_regex = regex.compile(r"(?!\w)'s\b", regex.I) @@ -36,6 +37,13 @@ def __init__(self, watch_media_id: int): def fetch(self): logger_background.info('Processing request to watch {}'.format(self._sanitize_title(str(self.watch_media)))) + + # skip attempt if media hasn't been released yet + if self.watch_media.release_date and self.watch_media.release_date > datetime.now().date(): + logger_background.warning('skipping search for "{}" since it has not been released yet ({})'.format( + self.watch_media, self.watch_media.release_date)) + return + valid_search_results = [] search = self._get_search_results() @@ -299,7 +307,7 @@ def _get_tmdb_media(self): def _get_search_results(self): # query the show name AND the season/episode name separately - # i.e search for "Atlanta" and "Atlanta s01e05" individually for best results + # i.e. search for "Atlanta" and "Atlanta s01e05" individually for best results watch_episode = self.watch_media # type: WatchTVEpisode show_result = self.tmdb_client.TV(watch_episode.watch_tv_show.tmdb_show_id) params = { diff --git a/src/nefarious/tasks.py b/src/nefarious/tasks.py index 8bb63d06..3adcff71 100644 --- a/src/nefarious/tasks.py +++ b/src/nefarious/tasks.py @@ -1,5 +1,4 @@ import os - import pytz from celery import chain from celery.signals import task_failure @@ -68,10 +67,17 @@ def log_exception(**kwargs): @app.task(base=QueueOnce, once={'graceful': True}) def watch_tv_show_season_task(watch_tv_season_id: int): processor = WatchTVSeasonProcessor(watch_media_id=watch_tv_season_id) - success = processor.fetch() - watch_tv_season = get_object_or_404(WatchTVSeason, pk=watch_tv_season_id) + # skip attempt if media hasn't been released yet + if watch_tv_season.release_date and watch_tv_season.release_date > datetime.now().date(): + logger_background.warning('skipping search for tv season "{}" since it has not been released yet ({})'.format( + watch_tv_season, watch_tv_season.release_date)) + return + + # make attempt + success = processor.fetch() + # success so update the season request instance as "collected" if success: season_request = WatchTVSeasonRequest.objects.filter( @@ -294,7 +300,7 @@ def wanted_media_task(): for media_type, data in wanted_media_data.items(): for media in data['query']: - # media has been released (or it's missing it's release date so try anyway) so create a task to try and fetch it + # media has been released (or it's missing its release date so try anyway) so create a task to try and fetch it if not media.release_date or media.release_date <= today: logger_background.info('Wanted {type}: {media}'.format(type=media_type, media=media)) # queue task for wanted media