class DownloadPopup(Toplevel): def __init__(self, master, info: dict, message_store: MessageStore, video_id: str = None): Toplevel.__init__(self, master) self.bind('<Escape>', lambda _: self.cancel()) self.bind('<Return>', lambda _: self.ok()) self.title('Get VOD') self.transient(master) self.grab_set() self.info: dict = info self.message_store: MessageStore = message_store self.chat_downloader: ChatDownloader = None self.updated_info: bool = False self.status_var = StringVar(value='...') self.content = Frame(self) self.content.pack(padx=20, pady=15) self.video_title_var = StringVar(value='') self.download_info_var = StringVar(value='') self.eta_var = StringVar(value='') Label(self.content, text='Enter a VOD URL or video ID:').pack(side=TOP, anchor=W, pady=(0, 5)) self.entry = Entry(self.content, width=50) self.entry.pack(side=TOP, padx=2, pady=(0, 5)) Label(self.content, textvariable=self.status_var).pack(side=TOP, anchor=W, pady=(0, 5)) self.progress_var = IntVar(value=0) self.progress = Progressbar(self.content, variable=self.progress_var, maximum=1) self.progress.pack(side=TOP, fill=X, padx=2) Label(self.content, textvariable=self.video_title_var).pack(side=TOP, anchor=W, pady=(0, 5)) Label(self.content, textvariable=self.download_info_var).pack(side=TOP, anchor=W, pady=(0, 5)) Label(self.content, textvariable=self.eta_var).pack(side=TOP, anchor=W, pady=(0, 5)) self.overwrite_cache_var = BooleanVar(value=False) self.overwrite_cache_check = Checkbutton(self.content, text='Overwrite cache', variable=self.overwrite_cache_var) self.overwrite_cache_check.pack(side=TOP, anchor=W, pady=(0, 5)) self.button = Button(self.content, text='OK', command=self.ok) self.button.pack(side=TOP) self.update() x_coord = self.master.winfo_x() + (self.master.winfo_width() // 2) - (self.winfo_width() // 2) y_coord = self.master.winfo_y() + (self.master.winfo_height() // 2) - (self.winfo_height() // 2) self.geometry(f'{self.winfo_width()}x{self.winfo_height()}+{x_coord}+{y_coord}') self.entry.focus_set() self.protocol('WM_DELETE_WINDOW', self.cancel) if video_id: self.entry.insert(0, video_id) self.overwrite_cache_check.focus_set() chat_filename: str = os.path.join(CACHE_FOLDER, f'chat-{video_id}.json') if not os.path.exists(chat_filename): self.ok() def cancel(self): if self.chat_downloader: self.chat_downloader.kill() self.info.clear() self.info.update({'title': 'Chat Player'}) self.destroy() def ok(self): self.button.config(state=DISABLED) self.overwrite_cache_check.config(state=DISABLED) self.status_var.set('Validating...') self.after(1, self.validate) def validate(self): video_id: str = self.entry.get() if 'http' in video_id or 'twitch.tv' in video_id: video_id = parse_url(video_id) if len(video_id) > 0 and video_exists(video_id): self.chat_downloader = ChatDownloader(video_id, overwrite_cache=self.overwrite_cache_var.get()) self.chat_downloader.start() self.after(1, self.download) else: self.status_var.set('Error: Invalid URL or video ID.') self.button.config(state=NORMAL) def download(self): if not self.chat_downloader.info: self.status_var.set('Getting info') self.after(100, self.download) elif not self.chat_downloader.messages: if not self.updated_info: self.status_var.set('Downloading chat') self.info.update(self.chat_downloader.info) self.video_title_var.set(self.info.get('title')) self.updated_info = True self.progress_var.set(self.chat_downloader.progress) self.download_info_var.set( f'{self.chat_downloader.num_messages} messages downloaded. ' f'Duration {self.chat_downloader.duration_done_str}/{self.chat_downloader.duration_str}.') self.eta_var.set(f'ETA: {self.chat_downloader.eta_str}') self.after(100, self.download) else: self.message_store.set_messages(self.chat_downloader.messages) self.destroy()