This commit is contained in:
geogolem 2025-11-30 03:15:22 +01:00 committed by GitHub
commit 5b067f441f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 87 additions and 53 deletions

View file

@ -3,7 +3,7 @@ import React, { Component } from 'react';
import NumberInput from 'Components/Form/NumberInput';
import SelectInput from 'Components/Form/SelectInput';
import TextInput from 'Components/Form/TextInput';
import { IN_LAST, IN_NEXT, NOT_IN_LAST, NOT_IN_NEXT } from 'Helpers/Props/filterTypes';
import { IN_LAST, IN_NEXT, IN_PAST, NOT_IN_LAST, NOT_IN_NEXT } from 'Helpers/Props/filterTypes';
import isString from 'Utilities/String/isString';
import translate from 'Utilities/String/translate';
import { NAME } from './FilterBuilderRowValue';
@ -57,6 +57,12 @@ function isInFilter(filterType) {
);
}
function isPastFutureFilter(filterType) {
return (
filterType === IN_PAST
);
}
class DateFilterBuilderRowValue extends Component {
//
@ -187,6 +193,10 @@ class DateFilterBuilderRowValue extends Component {
);
}
if (isPastFutureFilter(filterType)) {
return null;
}
return (
<TextInput
name={NAME}

View file

@ -62,7 +62,8 @@ export const possibleFilterTypes = {
{
key: filterTypes.NOT_IN_NEXT,
value: () => translate('FilterNotInNext')
}
},
{ key: filterTypes.IN_PAST, value: 'before today' }
],
[EQUAL]: [

View file

@ -8,6 +8,7 @@ export const IN_NEXT = 'inNext';
export const NOT_IN_NEXT = 'notInNext';
export const LESS_THAN = 'lessThan';
export const LESS_THAN_OR_EQUAL = 'lessThanOrEqual';
export const IN_PAST = 'inPast';
export const NOT_CONTAINS = 'notContains';
export const NOT_EQUAL = 'notEqual';
export const STARTS_WITH = 'startsWith';
@ -22,6 +23,7 @@ export const all = [
GREATER_THAN_OR_EQUAL,
LESS_THAN,
LESS_THAN_OR_EQUAL,
IN_PAST,
NOT_CONTAINS,
NOT_EQUAL,
IN_LAST,

View file

@ -74,6 +74,7 @@ function MovieIndexOverview(props: MovieIndexOverviewProps) {
tags,
hasFile,
isAvailable,
dateConsideredAvailable,
tmdbId,
imdbId,
studio,
@ -168,6 +169,7 @@ function MovieIndexOverview(props: MovieIndexOverviewProps) {
monitored={monitored}
hasFile={hasFile}
isAvailable={isAvailable}
dateConsideredAvailable={dateConsideredAvailable}
status={status}
width={posterWidth}
detailedProgressBar={overviewOptions.detailedProgressBar}

View file

@ -78,6 +78,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
studio,
added,
year,
dateConsideredAvailable,
inCinemas,
physicalRelease,
digitalRelease,
@ -222,6 +223,7 @@ function MovieIndexPoster(props: MovieIndexPosterProps) {
monitored={monitored}
hasFile={hasFile}
isAvailable={isAvailable}
dateConsideredAvailable={dateConsideredAvailable}
status={status}
width={posterWidth}
detailedProgressBar={detailedProgressBar}

View file

@ -18,6 +18,7 @@ interface MovieIndexProgressBarProps {
status: MovieStatus;
hasFile: boolean;
isAvailable: boolean;
dateConsideredAvailable: string;
width: number;
detailedProgressBar: boolean;
bottomRadius?: boolean;
@ -31,6 +32,7 @@ function MovieIndexProgressBar({
status,
hasFile,
isAvailable,
dateConsideredAvailable,
width,
detailedProgressBar,
bottomRadius,
@ -74,6 +76,7 @@ function MovieIndexProgressBar({
showText={detailedProgressBar}
width={width}
text={queueStatusText ? queueStatusText : movieStatus}
title={movieStatus === 'NotAvailable' ? dateConsideredAvailable : ''}
/>
);
}

View file

@ -80,6 +80,7 @@ function MovieIndexRow(props: MovieIndexRowProps) {
tmdbId,
imdbId,
isAvailable,
dateConsideredAvailable,
hasFile,
movieFile,
youTubeTrailerId,
@ -363,6 +364,7 @@ function MovieIndexRow(props: MovieIndexRowProps) {
monitored={monitored}
hasFile={hasFile}
isAvailable={isAvailable}
dateConsideredAvailable={dateConsideredAvailable}
status={status}
width={125}
detailedProgressBar={true}

View file

@ -95,6 +95,7 @@ interface Movie extends ModelBase {
grabbed?: boolean;
lastSearchTime?: string;
isAvailable: boolean;
dateConsideredAvailable: string;
isSaving?: boolean;
addOptions: MovieAddOptions;
}

View file

@ -473,6 +473,12 @@ export const defaultState = {
type: filterBuilderTypes.EXACT,
valueType: filterBuilderValueTypes.BOOL
},
{
name: 'dateConsideredAvailable',
label: translate('DateConsideredAvailable'),
type: filterBuilderTypes.DATE,
valueType: filterBuilderValueTypes.DATE
},
{
name: 'minimumAvailability',
label: () => translate('MinimumAvailability'),
@ -514,6 +520,12 @@ export const defaultState = {
label: () => translate('Popularity'),
type: filterBuilderTypes.NUMBER
},
{
name: 'minimumAvailabilityDate',
label: translate('MinimumAvailabilityDate'),
type: filterBuilderTypes.DATE,
valueType: filterBuilderValueTypes.DATE
},
{
name: 'certification',
label: () => translate('Certification'),

View file

@ -152,6 +152,14 @@ export const filterPredicates = {
return dateFilterPredicate(item.physicalRelease, filterValue, type);
},
dateConsideredAvailable: function(item, filterValue, type) {
return dateFilterPredicate(item.dateConsideredAvailable, filterValue, type);
},
minimumAvailabilityDate: function(item, filterValue, type) {
return dateFilterPredicate(item.minimumAvailabilityDate, filterValue, type);
},
digitalRelease: function(item, filterValue, type) {
return dateFilterPredicate(item.digitalRelease, filterValue, type);
},

View file

@ -316,12 +316,24 @@ export const defaultState = {
type: filterBuilderTypes.EXACT,
valueType: filterBuilderValueTypes.BOOL
},
{
name: 'dateConsideredAvailable',
label: translate('DateConsideredAvailable'),
type: filterBuilderTypes.DATE,
valueType: filterBuilderValueTypes.DATE
},
{
name: 'minimumAvailability',
label: () => translate('MinimumAvailability'),
type: filterBuilderTypes.EXACT,
valueType: filterBuilderValueTypes.MINIMUM_AVAILABILITY
},
{
name: 'minimumAvailabilityDate',
label: translate('MinimumAvailabilityDate'),
type: filterBuilderTypes.DATE,
valueType: filterBuilderValueTypes.DATE
},
{
name: 'title',
label: () => translate('Title'),

View file

@ -37,6 +37,9 @@ export default function(itemValue, filterValue, type) {
isAfter(itemValue, { [filterValue.time]: filterValue.value })
);
case filterTypes.IN_PAST:
return moment(itemValue).isBefore(new Date());
default:
return false;
}

View file

@ -305,6 +305,7 @@
"Database": "Database",
"DatabaseMigration": "Database Migration",
"Date": "Date",
"DateConsideredAvailable": "Date Considered Available",
"Dates": "Dates",
"Day": "Day",
"DayOfWeekAt": "{day} at {time}",
@ -1076,6 +1077,7 @@
"MinimumAge": "Minimum Age",
"MinimumAgeHelpText": "Usenet only: Minimum age in minutes of NZBs before they are grabbed. Use this to give new releases time to propagate to your usenet provider.",
"MinimumAvailability": "Minimum Availability",
"MinimumAvailabilityDate": "Minimum Availability Date",
"MinimumCustomFormatScore": "Minimum Custom Format Score",
"MinimumCustomFormatScoreHelpText": "Minimum custom format score allowed to download",
"MinimumCustomFormatScoreIncrement": "Minimum Custom Format Score Increment",

View file

@ -76,70 +76,40 @@ public string FolderName()
public bool IsAvailable(int delay = 0)
{
// the below line is what was used before delay was implemented, could still be used for cases when delay==0
// return (Status >= MinimumAvailability || (MinimumAvailability == MovieStatusType.PreDB && Status >= MovieStatusType.Released));
// This more complex sequence handles the delay
DateTime minimumAvailabilityDate;
if (MinimumAvailability is MovieStatusType.TBA or MovieStatusType.Announced)
{
minimumAvailabilityDate = DateTime.MinValue;
}
else if (MinimumAvailability == MovieStatusType.InCinemas && MovieMetadata.Value.InCinemas.HasValue)
{
minimumAvailabilityDate = MovieMetadata.Value.InCinemas.Value;
}
else
{
if (MovieMetadata.Value.PhysicalRelease.HasValue && MovieMetadata.Value.DigitalRelease.HasValue)
{
minimumAvailabilityDate = new DateTime(Math.Min(MovieMetadata.Value.PhysicalRelease.Value.Ticks, MovieMetadata.Value.DigitalRelease.Value.Ticks));
}
else if (MovieMetadata.Value.PhysicalRelease.HasValue)
{
minimumAvailabilityDate = MovieMetadata.Value.PhysicalRelease.Value;
}
else if (MovieMetadata.Value.DigitalRelease.HasValue)
{
minimumAvailabilityDate = MovieMetadata.Value.DigitalRelease.Value;
}
else
{
minimumAvailabilityDate = MovieMetadata.Value.InCinemas?.AddDays(90) ?? DateTime.MaxValue;
}
}
if (minimumAvailabilityDate == DateTime.MinValue || minimumAvailabilityDate == DateTime.MaxValue)
{
return DateTime.UtcNow >= minimumAvailabilityDate;
}
return DateTime.UtcNow >= minimumAvailabilityDate.AddDays(delay);
return DateTime.UtcNow >= GetReleaseDate(delay, true);
}
public DateTime? GetReleaseDate()
public DateTime? GetReleaseDate(int delay = 0, bool isAvailabilityCheck = false)
{
if (MinimumAvailability is MovieStatusType.TBA or MovieStatusType.Announced)
{
return new[] { MovieMetadata.Value.InCinemas, MovieMetadata.Value.DigitalRelease, MovieMetadata.Value.PhysicalRelease }
.Where(x => x.HasValue)
.Min();
if (isAvailabilityCheck)
{
return DateTime.MinValue;
}
else if (MovieMetadata.Value.InCinemas.HasValue || MovieMetadata.Value.DigitalRelease.HasValue || MovieMetadata.Value.PhysicalRelease.HasValue)
{
return new[] { MovieMetadata.Value.InCinemas, MovieMetadata.Value.DigitalRelease, MovieMetadata.Value.PhysicalRelease }
.Where(x => x.HasValue)
.Min()?.AddDays(delay);
}
}
if (MinimumAvailability == MovieStatusType.InCinemas && MovieMetadata.Value.InCinemas.HasValue)
else if (MinimumAvailability == MovieStatusType.InCinemas && MovieMetadata.Value.InCinemas.HasValue)
{
return MovieMetadata.Value.InCinemas.Value;
return MovieMetadata.Value.InCinemas.Value.AddDays(delay);
}
if (MovieMetadata.Value.DigitalRelease.HasValue || MovieMetadata.Value.PhysicalRelease.HasValue)
else if (MovieMetadata.Value.DigitalRelease.HasValue || MovieMetadata.Value.PhysicalRelease.HasValue)
{
return new[] { MovieMetadata.Value.DigitalRelease, MovieMetadata.Value.PhysicalRelease }
.Where(x => x.HasValue)
.Min();
.Min()?.AddDays(delay);
}
else if (!MovieMetadata.Value.InCinemas.HasValue && isAvailabilityCheck)
{
return DateTime.MaxValue;
}
return MovieMetadata.Value.InCinemas?.AddDays(90);
return MovieMetadata.Value.InCinemas?.AddDays(90 + delay);
}
public override string ToString()

View file

@ -63,7 +63,9 @@ public MovieResource()
// Editing Only
public bool Monitored { get; set; }
public MovieStatusType MinimumAvailability { get; set; }
public DateTime? MinimumAvailabilityDate { get; set; }
public bool IsAvailable { get; set; }
public DateTime? DateConsideredAvailable { get; set; }
public string FolderName { get; set; }
public int Runtime { get; set; }
@ -143,6 +145,8 @@ public static MovieResource ToResource(this Movie model, int availDelay, MovieTr
MinimumAvailability = model.MinimumAvailability,
IsAvailable = model.IsAvailable(availDelay),
DateConsideredAvailable = model.GetReleaseDate(availDelay),
MinimumAvailabilityDate = model.GetReleaseDate(),
FolderName = model.FolderName(),
Runtime = model.MovieMetadata.Value.Runtime,