diff --git a/src/frontend/src/app/settings/settings.component.html b/src/frontend/src/app/settings/settings.component.html index e451e70b..97d2c4cc 100644 --- a/src/frontend/src/app/settings/settings.component.html +++ b/src/frontend/src/app/settings/settings.component.html @@ -186,6 +186,28 @@ + +
+
+ Video Validation +
+
+
Automatically detect, blacklist, and retry fake videos.
+
Note This will also reject any bundled downloads (e.g. rar, tar, zip)
+
+ + +
+
+ + +
+
+
diff --git a/src/frontend/src/app/settings/settings.component.ts b/src/frontend/src/app/settings/settings.component.ts index 92bb910d..bf8092f8 100644 --- a/src/frontend/src/app/settings/settings.component.ts +++ b/src/frontend/src/app/settings/settings.component.ts @@ -52,6 +52,7 @@ export class SettingsComponent implements OnInit, AfterContentChecked { 'quality_profile_tv': [settings['quality_profile_tv'], Validators.required], 'quality_profile_movies': [settings['quality_profile_movies'], Validators.required], 'allow_hardcoded_subs': [settings['allow_hardcoded_subs'], Validators.required], + 'enable_video_detection': [settings['enable_video_detection'], Validators.required], 'exclusions': [settings['keyword_search_filters'] ? _.keys(settings['keyword_search_filters']) : []], 'language': [settings['language'], Validators.required], 'users': new FormArray([]), diff --git a/src/nefarious/importer/base.py b/src/nefarious/importer/base.py index f2ccaafd..a5bfdf5c 100644 --- a/src/nefarious/importer/base.py +++ b/src/nefarious/importer/base.py @@ -57,7 +57,7 @@ def ingest_path(self, file_path): if file_extension_match: # skip sample files if parser.sample_file_regex.search(file_name): - logger_background.warning('[NO_MATCH_SAMPLE] Not matching sample file "{}"'.format(file_path)) + logger_background.info('[NO_MATCH_SAMPLE] Not matching sample file "{}"'.format(file_path)) return False title = parser.match['title'] if not title: @@ -66,7 +66,7 @@ def ingest_path(self, file_path): title = new_title parser.match.update(parser_match) else: - logger_background.warning('[NO_MATCH_TITLE] Could not match file without title "{}"'.format(file_path)) + logger_background.info('[NO_MATCH_TITLE] Could not match file without title "{}"'.format(file_path)) return False file_extension = file_extension_match.group() if file_extension in video_extensions(): @@ -91,11 +91,11 @@ def ingest_path(self, file_path): logger_background.info('[MATCH] Saved media "{}" from file "{}"'.format(watch_media, file_path)) return watch_media else: # for/else - logger_background.warning('[NO_MATCH_MEDIA] No media match for title "{}" and file "{}"'.format(title, file_path)) + logger_background.info('[NO_MATCH_MEDIA] No media match for title "{}" and file "{}"'.format(title, file_path)) else: - logger_background.warning('[NO_MATCH_VIDEO] No valid video file extension for file "{}"'.format(file_path)) + logger_background.info('[NO_MATCH_VIDEO] No valid video file extension for file "{}"'.format(file_path)) else: - logger_background.warning('[NO_MATCH_EXTENSION] No file extension for file "{}"'.format(file_path)) + logger_background.info('[NO_MATCH_EXTENSION] No file extension for file "{}"'.format(file_path)) else: logger_background.info('[NO_MATCH_UNKNOWN] Unknown match for file "{}"'.format(file_path)) return False diff --git a/src/nefarious/migrations/0070_nefarioussettings_enable_fake_video_detection.py b/src/nefarious/migrations/0070_nefarioussettings_enable_fake_video_detection.py new file mode 100644 index 00000000..7696b6a5 --- /dev/null +++ b/src/nefarious/migrations/0070_nefarioussettings_enable_fake_video_detection.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.2 on 2022-07-04 14:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('nefarious', '0069_auto_20211128_1337'), + ] + + operations = [ + migrations.AddField( + model_name='nefarioussettings', + name='enable_fake_video_detection', + field=models.BooleanField(default=False), + ), + ] diff --git a/src/nefarious/migrations/0071_auto_20220704_2043.py b/src/nefarious/migrations/0071_auto_20220704_2043.py new file mode 100644 index 00000000..7701830e --- /dev/null +++ b/src/nefarious/migrations/0071_auto_20220704_2043.py @@ -0,0 +1,22 @@ +# Generated by Django 3.0.2 on 2022-07-04 20:43 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('nefarious', '0070_nefarioussettings_enable_fake_video_detection'), + ] + + operations = [ + migrations.RemoveField( + model_name='nefarioussettings', + name='enable_fake_video_detection', + ), + migrations.AddField( + model_name='nefarioussettings', + name='enable_video_detection', + field=models.BooleanField(default=True), + ), + ] diff --git a/src/nefarious/models.py b/src/nefarious/models.py index 7576e620..846e0335 100644 --- a/src/nefarious/models.py +++ b/src/nefarious/models.py @@ -48,8 +48,12 @@ class NefariousSettings(models.Model): quality_profile_tv = models.CharField(max_length=500, default=quality.PROFILE_ANY.name, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES)) quality_profile_movies = models.CharField(max_length=500, default=quality.PROFILE_HD_720P_1080P.name, choices=zip(quality.PROFILE_NAMES, quality.PROFILE_NAMES)) + # whether to allow hardcoded subtitles allow_hardcoded_subs = models.BooleanField(default=False) + # whether to enable video detection features (e.g. fake) + enable_video_detection = models.BooleanField(default=False) + # expects keyword/boolean pairs like {"x265": false, "265": false} keyword_search_filters = JSONField(blank=True, null=True) # type: dict diff --git a/src/nefarious/tasks.py b/src/nefarious/tasks.py index c0fa9cd2..ecb8ab6f 100644 --- a/src/nefarious/tasks.py +++ b/src/nefarious/tasks.py @@ -159,8 +159,9 @@ def completed_media_task(): logger_background.info('Media completed: {}'.format(media)) - # run video detection on the relevant video files for movies - if isinstance(media, WatchMovie): + # run video detection, if enabled, on the relevant video files for movies, staging_path + if nefarious_settings.enable_video_detection and isinstance(media, WatchMovie): + logger_background.info("[VIDEO_DETECTION] verifying '{}'".format(media)) staging_path = os.path.join( settings.INTERNAL_DOWNLOAD_PATH, settings.UNPROCESSED_PATH, @@ -168,9 +169,11 @@ def completed_media_task(): torrent.name, ) try: - if not VideoDetect.has_valid_video_in_path(staging_path): + if VideoDetect.has_valid_video_in_path(staging_path): + logger_background.info("[VIDEO_DETECTION] '{}' has valid video files".format(media)) + else: blacklist_media_and_retry(media) - logger_background.error("Blacklisting video '{}' because no valid video was found: {}".format(media, staging_path)) + logger_background.error("[VIDEO_DETECTION] blacklisting '{}' because no valid video was found: {}".format(media, staging_path)) continue except Exception as e: logger_background.exception(e) diff --git a/src/nefarious/video_detection.py b/src/nefarious/video_detection.py index 3a980d1a..99ebccb0 100644 --- a/src/nefarious/video_detection.py +++ b/src/nefarious/video_detection.py @@ -34,8 +34,7 @@ def __init__(self, video_path: str): @classmethod def has_valid_video_in_path(cls, path: str): - # TODO - remove once fixed bug https://github.com/lardbit/nefarious/issues/203 - return True + # TODO - this doesn't handle bundles (rar/zip/tar etc) since it won't find any "media" files files_to_verify = [] @@ -65,8 +64,8 @@ def has_valid_video_in_path(cls, path: str): return True return False - def is_correct_length(self, correct_duration: float): - return abs(self.duration - correct_duration) / correct_duration < self.MAX_VIDEO_DURATION_DIFFERENCE_RATIO + def is_correct_length(self, expected_duration: float): + return abs(self.duration - expected_duration) / expected_duration < self.MAX_VIDEO_DURATION_DIFFERENCE_RATIO def is_too_similar(self): return self.video_similarity_std <= self.MIN_VIDEO_SIMILARITY_STD