From 5e01315aa1ad0c56be33cb5b6a4d079068ee7145 Mon Sep 17 00:00:00 2001
From: pukkandan <pukkandan.ytdlp@gmail.com>
Date: Sat, 27 Aug 2022 07:22:48 +0530
Subject: [PATCH] [cache, extractor/youtube] Invalidate old cache

---
 yt_dlp/cache.py             | 19 ++++++++++++++-----
 yt_dlp/extractor/youtube.py |  2 +-
 yt_dlp/version.py           |  2 +-
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/yt_dlp/cache.py b/yt_dlp/cache.py
index 83351b797..602cb9edb 100644
--- a/yt_dlp/cache.py
+++ b/yt_dlp/cache.py
@@ -6,7 +6,8 @@
 import shutil
 import traceback
 
-from .utils import expand_path, write_json_file
+from .utils import expand_path, traverse_obj, version_tuple, write_json_file
+from .version import __version__
 
 
 class Cache:
@@ -45,12 +46,20 @@ def store(self, section, key, data, dtype='json'):
                 if ose.errno != errno.EEXIST:
                     raise
             self._ydl.write_debug(f'Saving {section}.{key} to cache')
-            write_json_file(data, fn)
+            write_json_file({'yt-dlp_version': __version__, 'data': data}, fn)
         except Exception:
             tb = traceback.format_exc()
             self._ydl.report_warning(f'Writing cache to {fn!r} failed: {tb}')
 
-    def load(self, section, key, dtype='json', default=None):
+    def _validate(self, data, after):
+        version = traverse_obj(data, 'yt-dlp_version')
+        if not version:  # Backward compatibility
+            data, version = {'data': data}, '2022.08.19'
+        if not after or version_tuple(version) > version_tuple(after):
+            return data['data']
+        self._ydl.write_debug(f'Discarding old cache from version {version} (need {after})')
+
+    def load(self, section, key, dtype='json', default=None, *, after=None):
         assert dtype in ('json',)
 
         if not self.enabled:
@@ -61,8 +70,8 @@ def load(self, section, key, dtype='json', default=None):
             try:
                 with open(cache_fn, encoding='utf-8') as cachef:
                     self._ydl.write_debug(f'Loading {section}.{key} from cache')
-                    return json.load(cachef)
-            except ValueError:
+                    return self._validate(json.load(cachef), after)
+            except (ValueError, KeyError):
                 try:
                     file_size = os.path.getsize(cache_fn)
                 except OSError as oe:
diff --git a/yt_dlp/extractor/youtube.py b/yt_dlp/extractor/youtube.py
index e9f8adbd1..38e5faa79 100644
--- a/yt_dlp/extractor/youtube.py
+++ b/yt_dlp/extractor/youtube.py
@@ -2659,7 +2659,7 @@ def _extract_n_function_name(self, jscode):
 
     def _extract_n_function_code(self, video_id, player_url):
         player_id = self._extract_player_info(player_url)
-        func_code = self.cache.load('youtube-nsig', player_id)
+        func_code = self.cache.load('youtube-nsig', player_id, after='2022.08.19')
         jscode = func_code or self._load_player(video_id, player_url)
         jsi = JSInterpreter(jscode)
 
diff --git a/yt_dlp/version.py b/yt_dlp/version.py
index 45f670b09..1ded15df4 100644
--- a/yt_dlp/version.py
+++ b/yt_dlp/version.py
@@ -1,6 +1,6 @@
 # Autogenerated by devscripts/update-version.py
 
-__version__ = '2022.08.19'
+__version__ = '2022.08.19.1'
 
 RELEASE_GIT_HEAD = '48c88e088'