""" Copyright (C) 2017 kanishka-linux kanishka.linux@gmail.com This file is part of kawaii-player. kawaii-player is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. kawaii-player is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with kawaii-player. If not, see <http://www.gnu.org/licenses/>. """ import os import re import importlib as imp import time import ipaddress import random import socket import shutil import urllib.request import hashlib from functools import partial from bs4 import BeautifulSoup from PyQt5 import QtCore, QtGui from PyQt5.QtCore import pyqtSlot, pyqtSignal from player_functions import ccurl, write_files, open_files, send_notification from player import PlayerWidget from multiprocessing import Process def observe_prop(ui, logr, mp, y=0): print(ui, logr, mp, y) while True: x = mp.time_pos if x is None: print(x) #ui.slider.setValue(y) else: pass #ui.slider.setValue(int(y)) time.sleep(0.5) y += 1 print(y, ui, logr, mp, ui.progress_counter) #ui.slider.setValue(int(y)) class Observe(QtCore.QThread): gotlink = pyqtSignal(float) def __init__(self, ui_widget, logr): QtCore.QThread.__init__(self) global ui, logger def __del__(self): self.wait() def run(self): while True: time.sleep(0.5) @pyqtSlot(float) def start_player_directly_observe(time_pos): global ui print(time_pos) #ui.tab_5.paintGL() ui.tab_5.update() ui.slider.setValue(int(time_pos)) ui.tab_5.update() #ui.slider.valueChanged(int(time_pos)) class FindPosterThread(QtCore.QThread): summary_signal = pyqtSignal(str, str, str) thumb_signal = pyqtSignal(list) imagesignal = pyqtSignal(dict, str, str) def __init__( self, ui_widget, logr, tmp, name, url=None, direct_url=None, copy_fanart=None, copy_poster=None, copy_summary=None, use_search=None, video_dir=None): QtCore.QThread.__init__(self) global ui, logger, TMPDIR, site, siteName ui = ui_widget logger = logr TMPDIR = tmp self.name = name self.url = url self.direct_url = direct_url self.copy_fanart = copy_fanart self.copy_poster = copy_poster self.copy_summary = copy_summary self.use_search = use_search self.video_dir = video_dir self.image_dict_list = {} self.dest_dir = '' self.summary_signal.connect(copy_information) self.thumb_signal.connect(update_playlist_widget) self.imagesignal.connect(update_image_list) site = ui.get_parameters_value(s='site')['site'] siteName = ui.get_parameters_value(s='siteName')['siteName'] self.site = site def __del__(self): self.wait() def remove_extra_thumbnails(self, dest): if os.path.exists(dest): small_nm_1, new_title = os.path.split(dest) small_nm_2 = '128px.'+new_title small_nm_3 = '480px.'+new_title small_nm_4 = 'label.'+new_title new_small_thumb = os.path.join(small_nm_1, small_nm_2) small_thumb = os.path.join(small_nm_1, small_nm_3) small_label = os.path.join(small_nm_1, small_nm_4) logger.info(new_small_thumb) if os.path.exists(new_small_thumb): os.remove(new_small_thumb) if os.path.exists(small_thumb): os.remove(small_thumb) if os.path.exists(small_label): os.remove(small_label) def create_extra_thumbnails(self, picn): if os.path.exists(picn) and os.stat(picn).st_size: ui.create_new_image_pixel(picn, 128) ui.create_new_image_pixel(picn, 480) label_name = 'label.'+os.path.basename(picn) path_thumb, new_title = os.path.split(picn) new_picn = os.path.join(path_thumb, label_name) if not os.path.exists(new_picn): ui.image_fit_option(picn, new_picn, fit_size=6, widget=ui.label) def run_curl(self, url=None, get_text=None, img_list=None): dest = dest_txt = ep_url = dest_txt = '' if img_list and len(img_list) == 7: img_url, dt, ep_url, local_path, site, img_key, dest_txt = img_list if not get_text: if url.startswith('http'): ccurl(url) try: if url: picn = url.split('#')[2] ui.image_fit_option(picn, picn, fit_size=6, widget=ui.label) if site.lower() == 'video': self.remove_extra_thumbnails(picn) self.create_extra_thumbnails(picn) except Exception as e: print(e) else: txt = 'Air Date: '+ dt + '\n\nEpisode Name: ' + img_key + '\n\nOverview: ' if ep_url and dest_txt: if ep_url.startswith('http'): content = ccurl(ep_url) soup = BeautifulSoup(content, 'lxml') txt_lnk = soup.find('textarea', {'name' : 'Overview_7'}) if txt_lnk: txt_val = txt_lnk.text txt_val = txt_val.strip() txt = txt + txt_val if dest_txt: write_files(dest_txt, txt, False) def update_image_list_method(self, image_dict, dest_dir, site): if (site != 'Music' and site != 'PlayLists' and site != 'NONE' and site != 'MyServer'): if not os.path.exists(dest_dir): os.makedirs(dest_dir) for img_key, img_val in image_dict.items(): img_url, dt, ep_url, local_path, site_record = img_val if site.lower() == 'video': if '\t' in local_path: path = local_path.split('\t')[0] path = local_path.replace('"', '') print(path) thumb_name_bytes = bytes(path, 'utf-8') h = hashlib.sha256(thumb_name_bytes) thumb_name = h.hexdigest() dest_txt = os.path.join(dest_dir, thumb_name+'.txt') dest_picn = os.path.join(dest_dir, thumb_name+'.jpg') else: dest_txt = os.path.join(dest_dir, img_key+'.txt') dest_picn = os.path.join(dest_dir, img_key+'.jpg') if img_url.startswith('//'): img_url = "http:"+img_url picn_url = img_url+'#-o#'+dest_picn img_val_copy = img_val.copy() img_val_copy.append(img_key) img_val_copy.append(dest_txt) self.run_curl(url=picn_url, get_text=False, img_list=img_val_copy) self.run_curl(url=picn_url, get_text=True, img_list=img_val_copy) def parse_tvdb(self, name, url): content = ccurl(url) soup = BeautifulSoup(content, 'lxml') sumry = soup.find('div', {'id':'content'}) linkLabels = soup.findAll('div', {'id':'content'}) logger.info(sumry) t_sum = re.sub('</h1>', '</h1><p>', str(sumry)) t_sum = re.sub('</div>', '</p></div>', str(t_sum)) soup = BeautifulSoup(t_sum, 'lxml') try: title = (soup.find('h1')).text except Exception as err_val: print(err_val) title = 'Title Not Available' title = re.sub('&', '&', title) try: sumr = (soup.find('p')).text except Exception as e: print(e, '--233--') sumr = "Not Available" try: link1 = linkLabels[1].findAll('td', {'id':'labels'}) logger.info(link1) labelId = "" for i in link1: j = i.text if "Genre" in j: k = str(i.findNext('td')) l = re.findall('>[^<]*', k) q = "" for p in l: q = q + " "+p.replace('>', '') k = q else: k = i.findNext('td').text k = re.sub('\n|\t', '', k) labelId = labelId + j +" "+k + '\n' except: labelId = "" summary = title+'\n\n'+labelId+ sumr summary = re.sub('\t', '', summary) fan_all = post_all = [] if self.copy_summary: self.summary_signal.emit(name, summary, 'summary') fan_all = re.findall('/[^"]tab=seriesfanart[^"]*', content) logger.info(fan_all) content1 = "" content2 = "" post_all = re.findall('/[^"]tab=seriesposters[^"]*', content) logger.info(post_all) direct_jpg = False fan_arr = [] post_arr = [] if not fan_all and not post_all: fan_all = re.findall('banners/seasons/[^"]*.jpg', content) post_all = fan_all direct_jpg = True if fan_all: url_fan_all = "http://thetvdb.com" + fan_all[0] logger.info(url_fan_all) if not direct_jpg: content1 = ccurl(url_fan_all) fan_arr = re.findall('banners/fanart/[^"]*jpg', content1) else: fan_arr = fan_all else: fan_arr = re.findall('banners/fanart/[^"]*.jpg', content) fan_arr = list(set(fan_arr)) fan_arr = random.sample(fan_arr, len(fan_arr)) if post_all: url_post_all = "http://thetvdb.com" + post_all[0] logger.info(url_post_all) if not direct_jpg: content2 = ccurl(url_post_all) post_arr = re.findall('banners/posters/[^"]*jpg', content2) else: post_arr = post_all else: post_arr = re.findall('banners/posters/[^"]*.jpg', content) post_arr = list(set(post_arr)) post_arr = random.sample(post_arr, len(post_arr)) return (post_arr, fan_arr) def parse_tmdb(self, name, final_link, thumb, fanart): url = final_link url_ext = ['discuss', 'reviews', 'posters', 'changes', 'videos', '#'] url_end = url.rsplit('/', 1)[1] if url_end in url_ext: url = url.rsplit('/', 1)[0] if '?' in url: url = url.split('?')[0] if url.endswith('/en'): url = url.rsplit('/', 1)[0] content = ccurl(url) soup = BeautifulSoup(content, 'lxml') #logger.info(soup.prettify()) title_div = soup.find('div', {'class':'title'}) if title_div: title = title_div.text else: title = name summ = soup.find('div', {'class':'overview'}) if summ: summary = summ.text.strip() else: summary = 'Not Available' cer_t = soup.find('div', {'class':'certification'}) if cer_t: cert = cer_t.text else: cert = 'None' genre = soup.find("section", {"class":"genres right_column"}) if genre: genres = genre.text.strip() genres = genres.replace('\n', ' ') genres = genres.replace('Genres', 'Genres:') else: genres = 'No Genres' new_summary = title.strip()+'\n\n'+cert.strip()+'\n'+genres.strip()+'\n\n'+summary.strip() if self.copy_summary: self.summary_signal.emit(name, new_summary, 'summary') if url.endswith('/en'): url = url.rsplit('/', 1)[0] burl = url + '/images/backdrops' url = url + '/images/posters' content = ccurl(url) bcontent = ccurl(burl) posters_link = re.findall('https://image.tmdb.org/[^"]*original[^"]*.jpg', content) fanart_link = re.findall('https://image.tmdb.org/[^"]*original[^"]*.jpg', bcontent) if not fanart_link: fanart_link = posters_link if posters_link: posters_link = random.sample(posters_link, len(posters_link)) ccurl(posters_link[0]+'#'+'-o'+'#'+thumb) if fanart_link: fanart_link = random.sample(fanart_link, len(fanart_link)) ccurl(fanart_link[0]+'#'+'-o'+'#'+fanart) def init_search(self, nam, url, direct_url, thumb, fanart, src_site): final_link = "" m = [] if self.use_search: if isinstance(self.use_search, bool): final_link, m = ui.metaengine.ddg_search(nam, 'tvdb') if not m: final_link, m = ui.metaengine.ddg_search(nam, 'tmdb') if m: src_site = 'tmdb' else: final_link, m = ui.metaengine.ddg_search(nam, self.use_search, direct_search=True) src_site = self.use_search else: if direct_url and url: if (".jpg" in url or ".png" in url or url.endswith('.webp')) and "http" in url: if self.copy_poster: ccurl(url+'#'+'-o'+'#'+thumb) elif self.copy_fanart: ccurl(url+'#'+'-o'+'#'+fanart) elif 'tvdb' in url or 'themoviedb' in url: final_link = url logger.info(final_link) m.append(final_link) if 'themoviedb' in url: src_site = 'tmdb' else: link = "http://thetvdb.com/index.php?seriesname="+nam+"&fieldlocation=1&language=7&genre=Animation&year=&network=&zap2it_id=&tvcom_id=&imdb_id=&order=translation&addedBy=&searching=Search&tab=advancedsearch" logger.info(link) content = ccurl(link) m = re.findall('/index.php[^"]tab=[^"]*', content) if not m: link = "http://thetvdb.com/index.php?seriesname="+nam+"&fieldlocation=2&language=7&genre=Animation&year=&network=&zap2it_id=&tvcom_id=&imdb_id=&order=translation&addedBy=&searching=Search&tab=advancedsearch" content = ccurl(link) m = re.findall('/index.php[^"]tab=[^"]*', content) if not m: link = "http://thetvdb.com/?string="+nam+"&searchseriesid=&tab=listseries&function=Search" content = ccurl(link) m = re.findall('/[^"]tab=series[^"]*lid=7', content) return (m, final_link, src_site) def run(self): name = self.name url = self.url direct_url = self.direct_url #print(name, url, direct_url, '--poster--thread--') fanart = os.path.join(TMPDIR, name+'-fanart.jpg') thumb = os.path.join(TMPDIR, name+'.jpg') fan_text = os.path.join(TMPDIR, name+'-fanart.txt') post_text = os.path.join(TMPDIR, name+'-poster.txt') logger.info(fanart) logger.info(thumb) final_link = "" m = [] if site == 'Music': final = '' if (self.copy_fanart and self.copy_poster and self.copy_summary): if not direct_url and not url: nam = ui.metaengine.name_adjust(name) url = "http://www.last.fm/search?q="+nam logger.info(url) wiki = "" content = ccurl(url) soup = BeautifulSoup(content, 'lxml') link = soup.findAll('div', {'class':'row clearfix'}) name3 = "" for i in link: j = i.findAll('a') for k in j: try: url = k['href'] if '?q=' not in url: logger.info(url) break except Exception as err: print(err, '--108--') logger.info(url) if url.startswith('http'): url = url else: url = "http://www.last.fm" + url logger.info(url) img_url = url+'/+images' wiki_url = url + '/+wiki' logger.info(wiki_url) content = ccurl(wiki_url) soup = BeautifulSoup(content, 'lxml') link = soup.find('div', {'class':'wiki-content'}) if link: wiki = link.text self.summary_signal.emit(name, wiki, 'summary') content = ccurl(img_url) soup = BeautifulSoup(content, 'lxml') link = soup.findAll('ul', {'class':'image-list'}) img = [] for i in link: j = i.findAll('img') for k in j: l = k['src'] u1 = l.rsplit('/', 2)[0] u2 = l.split('/')[-1] u = u1 + '/770x0/'+u2 img.append(u) img = list(set(img)) logger.info(len(img)) thumb = os.path.join(TMPDIR, name+'.jpg') if img: url = img[0] try: ccurl(url, curl_opt='-o', out_file=thumb) except Exception as err: print(err, '--151--') elif (self.copy_poster or self.copy_fanart) and url and direct_url: if 'last.fm' in url: logger.info('--artist-link---{0}'.format(url)) content = ccurl(url) soup = BeautifulSoup(content, 'lxml') link = soup.findAll('img') url1Code = url.split('/')[-1] found = None for i in link: if 'src' in str(i): j = i['src'] k = j.split('/')[-1] if url1Code == k: found = j break logger.info(str(found)) if found: u1 = found.rsplit('/', 2)[0] u2 = found.split('/')[-1] final = u1 + '/770x0/'+u2 logger.info(final) elif (".jpg" in url or ".png" in url) and url.startswith('http'): final = url else: final = '' try: if final.startswith('http'): ccurl(final, curl_opt='-o', out_file=thumb) except Exception as e: print(e) else: nam = ui.metaengine.name_adjust(name) src_site = 'tvdb' epn_arr = [] post_val = '' fan_val = '' logger.debug('\nvideo_dir={0}\n'.format(self.video_dir)) if site.lower() == 'video' and self.video_dir: video_db = os.path.join(ui.home_folder, 'VideoDB', 'Video.db') if os.path.exists(video_db): epn_arr_tmp = ui.media_data.get_video_db(video_db, "Directory", self.video_dir) for i in epn_arr_tmp: epn_name = i[0]+' '+i[1] logger.debug(epn_name) epn_arr.append(epn_name) elif self.video_dir: new_name_with_info = self.video_dir.strip() extra_info = '' if ' ' in new_name_with_info: name_title = new_name_with_info.split(' ')[0] extra_info = new_name_with_info.split(' ')[1] else: name_title = new_name_with_info if site.lower() == 'subbedanime' or site.lower() == 'dubbedanime' and siteName: hist_site = os.path.join(ui.home_folder, 'History', site, siteName, name_title) else: hist_site = os.path.join(ui.home_folder, 'History', site, name_title) hist_epn = os.path.join(hist_site, 'Ep.txt') logger.info(hist_epn) if os.path.exists(hist_epn): lines = open_files(hist_epn, True) for i in lines: i = i.strip() j = i.split(' ') if len(j) == 1: epn_arr.append(i+' '+i+' '+name) elif len(j) >= 2: epn_arr.append(i+' '+name) if ui.series_info_dict.get(name) and not epn_arr: logger.debug('getting values from cache') dict_val = ui.series_info_dict.get(name) post_arr = dict_val.get('poster') fan_arr = dict_val.get('fanart') fan_index = dict_val.get('f') post_index = dict_val.get('p') if fan_index < len(fan_arr): fan_val = fan_arr[fan_index] fan_index = (fan_index + 1) % len(fan_arr) dict_val.update({'f':fan_index}) if post_index < len(post_arr): post_val = post_arr[post_index] post_index = (post_index + 1) % len(post_arr) dict_val.update({'p':post_index}) ui.series_info_dict.update({name:dict_val}) if isinstance(self.use_search, bool): src_site = 'tvdb' else: src_site = self.use_search else: m, final_link, src_site = self.init_search( nam, url, direct_url, thumb, fanart, src_site ) if (m and src_site in ['tvdb', 'tvdb+g', 'tvdb+ddg']) or post_val or fan_val: if post_val or fan_val: if post_val: url = "http://thetvdb.com/" + post_val ccurl(url+'#'+'-o'+'#'+thumb) if fan_val: url = "http://thetvdb.com/" + fan_val ccurl(url+'#'+'-o'+'#'+fanart) else: if not final_link: n = re.sub('amp;', '', m[0]) elist = re.sub('tab=series', 'tab=seasonall', n) url = "http://thetvdb.com" + n logger.info(url) elist_url = "http://thetvdb.com" + elist else: url = final_link post_arr, fan_arr = self.parse_tvdb(name, url) if post_arr: url = "http://thetvdb.com/" + post_arr[0] ccurl(url+'#'+'-o'+'#'+thumb) logger.info(post_arr) if fan_arr: #if ui.player_theme != 'default': fan_arr = [i for i in fan_arr if 'vignette' not in i] if fan_arr: url = "http://thetvdb.com/" + fan_arr[0] ccurl(url+'#'+'-o'+'#'+fanart) logger.debug(fan_arr) fan_arr.sort() post_arr.sort() ui.series_info_dict.update( { name:{ 'fanart':fan_arr.copy(), 'poster':post_arr.copy(), 'f':0, 'p':0 } } ) elist_url = re.sub('tab=series', 'tab=seasonall', final_link) if epn_arr: ui.metaengine.getTvdbEpnInfo( elist_url, epn_arr=epn_arr.copy(), site=site, name=name, thread=self, video_dir=self.video_dir ) image_dict = self.image_dict_list.copy() dest_dir = self.dest_dir self.imagesignal.emit(image_dict, dest_dir, site) elif m and src_site in ['tmdb', 'tmdb+g', 'tmdb+ddg']: self.parse_tmdb(name, final_link, thumb, fanart) @pyqtSlot(str, str, str) def copy_information(nm, txt, val): global ui if val == 'summary': ui.copySummary(new_name=nm, copy_sum=txt) new_copy_sum = 'Wait..Downloading Poster and Fanart..\n\n'+txt ui.text.setText(new_copy_sum) elif val == 'poster': ui.copyImg(new_name=nm) elif val == 'fanart': ui.copyFanart(new_name=nm) @pyqtSlot(list) def update_playlist_widget(epn_arr): ui.update_list2(epn_arr) @pyqtSlot(dict, str, str) def update_image_list(image_dict, dest_dir, site): global ui if dest_dir: update_image_list_method(image_dict, dest_dir, site) def update_image_list_method(image_dict, dest_dir, site): global ui if (site != 'Music' and site != 'PlayLists' and site != 'NONE' and site != 'MyServer'): r = 0 start_pt = 0 start_now = True length = 0 txt_count = 0 if not os.path.exists(dest_dir): os.makedirs(dest_dir) for img_key, img_val in image_dict.items(): img_url, dt, ep_url, local_path, site_record = img_val if site.lower() == 'video': if '\t' in local_path: path = local_path.split('\t')[0] path = local_path.replace('"', '') thumb_name_bytes = bytes(path, 'utf-8') h = hashlib.sha256(thumb_name_bytes) thumb_name = h.hexdigest() dest_txt = os.path.join(dest_dir, thumb_name+'.txt') dest_picn = os.path.join(dest_dir, thumb_name+'.jpg') else: dest_txt = os.path.join(dest_dir, img_key+'.txt') dest_picn = os.path.join(dest_dir, img_key+'.jpg') if img_url.startswith('//'): img_url = "http:"+img_url picn_url = img_url+'#-o#'+dest_picn img_val_copy = img_val.copy() img_val_copy.append(img_key) img_val_copy.append(dest_txt) ui.downloadWget.append( DownloadThread(ui, picn_url, img_list=img_val_copy) ) length = len(ui.downloadWget) ui.downloadWget[length-1].finished.connect( partial(ui.download_thread_finished, dest_picn, r, length-1)) if not ui.wget_counter_list: ui.wget_counter_list = [1 for i in range(len(image_dict))] ui.downloadWget[length-1].start() r += 1 ui.downloadWgetText.append( DownloadThread(ui, picn_url, img_list=img_val_copy, get_text=True) ) length_text = len(ui.downloadWgetText) ui.downloadWgetText[length_text-1].finished.connect( partial(ui.download_thread_text_finished, dest_txt, txt_count, length_text-1) ) if not ui.wget_counter_list_text: ui.wget_counter_list_text = [1 for i in range(len(image_dict))] ui.downloadWgetText[length_text-1].start() txt_count += 1 class YTdlThread(QtCore.QThread): gotlink = pyqtSignal(str, str) def __init__(self, ui_widget, logr, url, quality, path, loger, nm, hdr): QtCore.QThread.__init__(self) global ui, logger ui = ui_widget logger = logr self.url = url self.quality = quality self.path = path self.loger = loger self.nm = nm self.hdr = hdr self.gotlink.connect(start_player_directly) def __del__(self): self.wait() def run(self): final_url = '' try: final_url = ui.yt.get_yt_url(self.url, self.quality, self.path, self.loger, mode='a+v') self.gotlink.emit(final_url, self.nm) try: if not self.nm: req = urllib.request.Request( self.url, data=None, headers={'User-Agent': 'Mozilla/5.0'}) f = urllib.request.urlopen(req) content = f.read().decode('utf-8') soup = BeautifulSoup(content, 'lxml') title = soup.title.text.replace(' - YouTube', '').strip() logger.info(title) ui.epn_name_in_list = title except Exception as e: print(e, '---2877---') except Exception as e: print(e, '--2865--') @pyqtSlot(str) def start_player_directly(final_url, nm): global ui if final_url: print(final_url, '--youtube--') ui.epn_name_in_list = nm #ui.watchDirectly(final_url, nm, 'no') ui.epnfound_now_start_player(final_url, nm) class UpdateMusicThread(QtCore.QThread): music_db_update = pyqtSignal(str) def __init__(self, ui_widget, music_db, music_file, music_file_bak): QtCore.QThread.__init__(self) global ui ui = ui_widget self.music_db = music_db self.music_file = music_file self.music_file_bak = music_file_bak self.music_db_update.connect(update_music_db_onstart) def __del__(self): self.wait() def run(self): self.music_db_update.emit('start') ui.media_data.update_on_start_music_db(self.music_db, self.music_file, self.music_file_bak) self.music_db_update.emit('end') @pyqtSlot(str) def update_music_db_onstart(val): global ui if val == 'start': ui.text.setText('Wait..Checking New Files') else: ui.text.setText('Finished Checking') class DownloadThread(QtCore.QThread): def __init__(self, ui_widget, url, img_list=None, get_text=None): QtCore.QThread.__init__(self) global ui self.url = url self.interval = 1 self.picn = 'picn' ui = ui_widget if img_list: """img_list=[img_url, date, ep_url, local_path, site, img_key, dest_dir]""" self.img_list = img_list.copy() else: self.img_list = [] if get_text: self.get_text = True else: self.get_text = False def __del__(self): self.wait() def remove_extra_thumbnails(self, dest): if os.path.exists(dest): small_nm_1, new_title = os.path.split(dest) small_nm_2 = '128px.'+new_title small_nm_3 = '480px.'+new_title small_nm_4 = 'label.'+new_title new_small_thumb = os.path.join(small_nm_1, small_nm_2) small_thumb = os.path.join(small_nm_1, small_nm_3) small_label = os.path.join(small_nm_1, small_nm_4) logger.info(new_small_thumb) if os.path.exists(new_small_thumb): os.remove(new_small_thumb) if os.path.exists(small_thumb): os.remove(small_thumb) if os.path.exists(small_label): os.remove(small_label) def create_extra_thumbnails(self, picn): if os.path.exists(picn) and os.stat(picn).st_size: ui.create_new_image_pixel(picn, 128) ui.create_new_image_pixel(picn, 480) label_name = 'label.'+os.path.basename(picn) path_thumb, new_title = os.path.split(picn) new_picn = os.path.join(path_thumb, label_name) if not os.path.exists(new_picn): ui.image_fit_option(picn, new_picn, fit_size=6, widget=ui.label) def run(self): dest = dest_txt = ep_url = dest_txt = '' if self.img_list and len(self.img_list) == 7: img_url, dt, ep_url, local_path, site, img_key, dest_txt = self.img_list if not self.get_text: if self.url.startswith('http'): ccurl(self.url) try: if self.url: self.picn = self.url.split('#')[2] ui.image_fit_option(self.picn, self.picn, fit_size=6, widget=ui.label) if site.lower() == 'video': self.remove_extra_thumbnails(self.picn) self.create_extra_thumbnails(self.picn) except Exception as e: print(e) else: txt = 'Air Date: '+ dt + '\n\nEpisode Name: ' + img_key + '\n\nOverview: ' if ep_url and dest_txt: if ep_url.startswith('http'): content = ccurl(ep_url) soup = BeautifulSoup(content, 'lxml') txt_lnk = soup.find('textarea', {'name' : 'Overview_7'}) if txt_lnk: txt_val = txt_lnk.text txt_val = txt_val.strip() txt = txt + txt_val if dest_txt: write_files(dest_txt, txt, False) class PlayerWaitThread(QtCore.QThread): wait_signal = pyqtSignal(str) def __init__(self, ui_widget, command): QtCore.QThread.__init__(self) global ui ui = ui_widget self.command = command self.wait_signal.connect(start_new_player_instance) def __del__(self): self.wait() def run(self): print('{0}: Running'.format(ui.player_val)) while ui.mpvplayer_val.processId() > 0: time.sleep(0.5) print('{0} Player still alive'.format(ui.player_val)) self.wait_signal.emit(self.command) @pyqtSlot(str) def start_new_player_instance(command): global ui ui.infoPlay(command) class GetSubThread(QtCore.QThread): sub_signal = pyqtSignal(str) def __init__(self, ui_widget, url, wait_time=None): QtCore.QThread.__init__(self) global ui ui = ui_widget self.url = url self.sub_signal.connect(load_external_sub_signal) if wait_time: if isinstance(wait_time, int): self.wait_time = wait_time else: self.wait_time = 0 else: self.wait_time = 2 def __del__(self): self.wait() def run(self): sub_name_bytes = bytes(self.url, 'utf-8') h = hashlib.sha256(sub_name_bytes) sub_name = h.hexdigest() sub_name_path = os.path.join(ui.yt_sub_folder, sub_name) try: req = urllib.request.Request(self.url) response = urllib.request.urlopen(req) content = response.read().decode('utf-8') content_type = response.info()['content-type'] if 'text/ass' in content_type: ext = '.ass' elif 'text/srt' in content_type: ext = '.srt' else: ext = '.vtt' subtitle_path = sub_name_path + ext write_files(subtitle_path, content, line_by_line=False) except Exception as err: ui.logger.error(err) ext = '.vtt' subtitle_path = sub_name_path + ext content = ccurl(self.url, curl_opt='-o', out_file=subtitle_path) if os.name == 'nt': subtitle_path = 'file:///' + subtitle_path.replace('\\', '/') time.sleep(self.wait_time) if ui.player_val.lower() == 'mplayer': command = 'sub_load "{}"'.format(subtitle_path) else: command = 'sub-add "{}" select'.format(subtitle_path) self.sub_signal.emit(command) @pyqtSlot(str) def load_external_sub_signal(command): global ui ui.mpv_execute_command(command, ui.cur_row) class PlayerGetEpn(QtCore.QThread): get_epn_signal = pyqtSignal(str, str) get_offline_signal = pyqtSignal(str, int) get_epn_signal_list = pyqtSignal(list, str) get_offline_signal_list = pyqtSignal(list, int) get_listfound_signal = pyqtSignal(list) get_title_signal = pyqtSignal(str, str) get_offline_signal_type_three = pyqtSignal(str, int, str, str) get_offline_signal_list_type_three = pyqtSignal(list, int, str, str) final_epn_prefetch_signal = pyqtSignal(str, int, str) def __init__(self, ui_widget, logr, epn_type, *args): QtCore.QThread.__init__(self) global ui, logger ui = ui_widget logger = logr self.epn_type = epn_type self.site_var = None param_dict = ui.get_parameters_value(s='site') self.site_name = param_dict['site'] if self.epn_type in ['yt', 'yt_title', 'yt+title', 'yt_music', 'yt_prefetch_av', 'yt_prefetch_a']: self.final = args[0] self.quality = args[1] self.yt_path = args[2] self.row = args[3] elif self.epn_type in ['addons', 'type_one', 'type_two', 'type_three']: self.name = args[0] self.epn = args[1] self.mirrorNo = args[2] self.quality = args[3] self.row = args[4] if self.epn_type in ['type_two', 'type_one', 'type_three']: if self.epn_type == 'type_three': self.site = args[5] self.siteName = args[6] self.epnname = args[7] if self.site_name != self.site: plugin_path = os.path.join(ui.home_folder, 'src', 'Plugins', self.site+'.py') if os.path.exists(plugin_path): module = imp.import_module(self.site, plugin_path) self.site_var = getattr(module, self.site)(ui.tmp_download_folder) else: self.siteName = args[5] if self.epn_type == 'type_one': self.category = args[6] elif self.epn_type == 'offline': self.row = args[0] self.mode = args[1] elif self.epn_type == 'list': self.name = args[0] self.opt = args[1] self.depth_list = args[2] self.extra_info = args[3] self.siteName = args[4] self.category = args[5] self.row = args[6] else: pass #self.command = command logger.info(args) self.get_epn_signal.connect(connect_to_epn_generator) self.get_epn_signal_list.connect(connect_to_epn_generator_list) self.get_offline_signal.connect(connect_to_offline_mode) self.get_offline_signal_list.connect(connect_to_offline_mode_list) self.get_offline_signal_type_three.connect(connect_to_offline_mode_type_three) self.get_offline_signal_list_type_three.connect(connect_to_offline_mode_list_type_three) self.get_listfound_signal.connect(connect_to_listfound_signal) self.get_title_signal.connect(connect_post_title) self.final_epn_prefetch_signal.connect(connect_prefetch_slot) def __del__(self): self.wait() def run(self): finalUrl = "" nosignal = False mylist = [] try: if hasattr(self, "final"): self.final = self.final.replace('"', "") if hasattr(self, "mode"): logger.debug('type={}, mode={}'.format(self.epn_type, self.mode)) if self.epn_type == 'yt': finalUrl = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode='a+v') elif self.epn_type == 'yt_music': finalUrl = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode='music') elif self.epn_type == 'yt_prefetch_av': if ui.use_single_network_stream: ytmode = 'offline' else: ytmode = 'a+v' if self.final.startswith("http"): finalUrl = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode=ytmode) else: finalUrl = self.final elif self.epn_type == 'yt_prefetch_a': if self.final.startswith("http"): finalUrl = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode='music') else: finalUrl = self.final elif self.epn_type == 'yt_title': finalUrl = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode='TITLE') elif self.epn_type == 'yt+title': finalUrl = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode='a+v') self.get_epn_signal.emit(finalUrl, '-1') title = ui.yt.get_yt_url(self.final, self.quality, self.yt_path, logger, mode='TITLE') self.get_title_signal.emit(title, self.final) nosignal = True elif self.epn_type == 'addons': finalUrl = ui.site_var.getFinalUrl(self.name, self.epn, self.mirrorNo, self.quality) elif self.epn_type == 'type_three': if self.site_var: if self.siteName: finalUrl = self.site_var.getFinalUrl( self.name, self.epn, self.mirrorNo, self.quality, sn=self.siteName ) else: finalUrl = self.site_var.getFinalUrl( self.name, self.epn, self.mirrorNo, self.quality ) else: if self.siteName: finalUrl = ui.site_var.getFinalUrl( self.name, self.epn, self.mirrorNo, self.quality, sn=self.siteName ) else: finalUrl = ui.site_var.getFinalUrl( self.name, self.epn, self.mirrorNo, self.quality ) elif self.epn_type == 'type_one': finalUrl = ui.site_var.getFinalUrl(self.siteName, self.name, self.epn, self.mirrorNo, self.category, self.quality) elif self.epn_type == 'type_two': finalUrl = ui.site_var.getFinalUrl(self.siteName, self.name, self.epn, self.mirrorNo, self.quality) elif self.epn_type == 'offline': finalUrl = ui.epn_return(self.row, mode=self.mode) logger.debug(finalUrl) elif self.epn_type == 'list': mytuple = ui.site_var.getEpnList(self.name, self.opt, self.depth_list, self.extra_info, self.siteName, self.category) for i in mytuple: mylist.append(i) mylist.append(self.name) mylist.append(self.extra_info) mylist.append(self.siteName) mylist.append(self.opt) mylist.append(self.row) except Exception as err: logger.error('{0}::--984--'.format(err)) if nosignal: pass else: if self.epn_type != 'list' and self.epn_type != 'yt_title': ui.epnfound_final_link = finalUrl if not isinstance(finalUrl, list): if self.epn_type == 'offline': self.get_offline_signal.emit(finalUrl, self.row) elif self.epn_type == 'type_three': self.get_offline_signal_type_three.emit( finalUrl, self.row, self.name, self.epnname ) elif self.epn_type == 'list': self.get_listfound_signal.emit(mylist) elif self.epn_type == 'yt_title': self.get_title_signal.emit(finalUrl, self.final) elif self.epn_type in ['yt_prefetch_av', 'yt_prefetch_a']: if ui.player_val == "libmpv": logger.debug(finalUrl) ui.tab_5.prefetch_url = (finalUrl, self.row, self.epn_type) else: self.final_epn_prefetch_signal.emit(finalUrl, self.row, self.epn_type) else: self.get_epn_signal.emit(finalUrl, str(self.row)) else: if self.epn_type == 'offline': self.get_offline_signal_list.emit(finalUrl, self.row) elif self.epn_type == 'type_three': self.get_offline_signal_list_type_three.emit( finalUrl, self.row, self.name, self.epnname ) else: self.get_epn_signal_list.emit(finalUrl, str(self.row)) @pyqtSlot(str, str) def connect_to_epn_generator(url, row): global ui if row == '-1': ui.watchDirectly(url, '', 'no') else: ui.epnfound_now_start_player(url, row) @pyqtSlot(str, int) def connect_to_offline_mode(url, row): global ui ui.start_offline_mode_post(url, row) @pyqtSlot(list, int) def connect_to_offline_mode_list(url, row): global ui ui.start_offline_mode_post(url, row) @pyqtSlot(str, int, str, str) def connect_to_offline_mode_type_three(url, row, name, epn): global ui ui.start_offline_mode_post(url, row, name, epn) @pyqtSlot(list, int, str, str) def connect_to_offline_mode_list_type_three(url, row, name, epn): global ui ui.start_offline_mode_post(url, row, name, epn) @pyqtSlot(list, str) def connect_to_epn_generator_list(url, row): global ui ui.epnfound_now_start_player(url, row) @pyqtSlot(str, int, str) def connect_prefetch_slot(url, row, mode): global ui ui.epnfound_now_start_prefetch(url, row, mode) @pyqtSlot(list) def connect_to_listfound_signal(mylist): global ui ui.listfound(send_list=mylist) @pyqtSlot(str, str) def connect_post_title(epn_title, tpath): global ui if epn_title: ui.epn_name_in_list = epn_title.strip() file_entry = ui.epn_name_in_list+' '+tpath+' '+'NONE' else: ui.epn_name_in_list = 'No Title' file_entry = tpath.split('/')[-1]+' '+tpath+' '+'NONE' if ui.list1.currentItem(): pls_name = ui.list1.currentItem().text() else: pls_name = 'TMP_PLAYLIST' file_name = os.path.join(ui.home_folder, 'Playlists', pls_name) if not os.path.exists(file_name): pls_name = 'TMP_PLAYLIST' file_name = os.path.join(ui.home_folder, 'Playlists', pls_name) if not os.path.exists(file_name): f = open(file_name, 'w').close() write_files(file_name, file_entry, True) list_item = ui.list1.findItems(pls_name, QtCore.Qt.MatchExactly) item = None if len(list_item) > 0: for i in list_item: row = ui.list1.row(i) ui.list1.setFocus() ui.list1.setCurrentRow(row) item = ui.list1.item(row) else: item = ui.list1.item(0) if item: ui.list1.itemDoubleClicked['QListWidgetItem*'].emit(item) class GetIpThread(QtCore.QThread): got_ip_signal = pyqtSignal(str) def __init__(self, ui_widget, interval=None, ip_file=None): QtCore.QThread.__init__(self) global ui ui = ui_widget if not interval: self.interval = (3600) else: self.interval = interval * (3600) self.got_ip_signal.connect(set_my_ip_function) self.ip_file = ip_file def __del__(self): self.wait() def run(self): while True: try: my_ip = str(ccurl('https://diagnostic.opendns.com/myip')) try: ip_obj = ipaddress.ip_address(my_ip) except Exception as e: print(e) my_ip = 'none' except Exception as e: print(e) my_ip = 'none' self.got_ip_signal.emit(my_ip) print(my_ip, '--from-GetIpThread--', self.interval) time.sleep(self.interval) @pyqtSlot(str) def set_my_ip_function(my_ip): global ui if my_ip.lower() != 'none': ui.my_public_ip = my_ip print(ui.cloud_ip_file) if ui.cloud_ip_file: if os.path.exists(ui.cloud_ip_file): f = open(ui.cloud_ip_file, 'w') f.write(my_ip) f.close() else: print('cloud ip file is not available') else: print('Cloud File Does not exists') class ThreadingThumbnail(QtCore.QThread): def __init__(self, ui_widget, logr, path, picn, inter, size): QtCore.QThread.__init__(self) global ui, logger ui = ui_widget logger = logr self.path = path self.picn = picn self.inter = inter self.interval = 1 self.size = size def __del__(self): self.wait() def run(self): logger.info(self.path) if not os.path.exists(self.picn) and self.path: try: if (self.path.startswith('http') and (self.path.endswith('.jpg') or self.path.endswith('.png') or self.path.endswith('.image'))): ccurl(self.path+'#'+'-o'+'#'+self.picn) ui.image_fit_option(self.picn, self.picn, fit_size=6, widget=ui.label) else: ui.generate_thumbnail_method(self.picn, self.inter, self.path, width_allowed=self.size) except Exception as e: logger.info("Thumbnail Generation Exception: {0}".format(e)) print(e,'--548--') class SetThumbnail(QtCore.QThread): setThumb = pyqtSignal(int, str, str) def __init__(self, ui_widget, logr, epn_arr, update_pl, title_list): QtCore.QThread.__init__(self) global ui, logger ui = ui_widget logger = logr self.epn_arr = epn_arr.copy() self.update_pl = update_pl self.title_list = title_list self.setThumb.connect(apply_thumbnail_to_playlist) def __del__(self): self.wait() def run(self): generate_thumbnail = False if ui.list1.currentItem(): txt = ui.list1.currentItem().text() if txt == self.title_list: generate_thumbnail = True if generate_thumbnail or ui.show_search_thumbnail: for i, k in enumerate(self.epn_arr): if ui.list_with_thumbnail and self.update_pl: self.setThumb.emit(i, k, self.title_list) @pyqtSlot(int, str, str) def apply_thumbnail_to_playlist(k, i, title): try: if k < ui.list2.count(): icon_name = ui.get_thumbnail_image_path(k, i, title_list=title) if ui.view_mode == "thumbnail_light": size = 256 else: size = 128 icon_new_pixel = ui.create_new_image_pixel(icon_name, size) if os.path.exists(icon_new_pixel): ui.list2.item(k).setIcon(QtGui.QIcon(icon_new_pixel)) if ui.view_mode == "thumbnail_light" and ui.list_poster.title_clicked: ui.list_poster.item(k).setIcon(QtGui.QIcon(icon_new_pixel)) except Exception as e: print(e) class SetThumbnailGrid(QtCore.QThread): setThumbGrid = pyqtSignal(int, str, str, int, tuple, int, str) def __init__(self, ui_widget, logr, browse_cnt, picn, val, fit_size, widget_size, length, nameEpn, path=None): QtCore.QThread.__init__(self) global ui, logger ui = ui_widget logger = logr self.browse_cnt = browse_cnt self.picn = picn self.val = val self.fit_size = fit_size self.widget_size = widget_size self.length = length self.nameEpn = nameEpn self.setThumbGrid.connect(apply_to_thumbnail_grid) self.path = path def __del__(self): self.wait() def run(self): counter_limit = 10 if self.path is not None: if self.path.startswith('http'): counter_limit = 120 counter = 0 while True and counter < counter_limit: if os.path.isfile(self.picn): if os.stat(self.picn).st_size: break time.sleep(0.5) counter += 1 if os.path.exists(self.picn): self.setThumbGrid.emit(self.browse_cnt, self.picn, self.val, self.fit_size, self.widget_size, self.length, self.nameEpn) @pyqtSlot(int, str, str, int, tuple, int, str) def apply_to_thumbnail_grid(browse_cnt, picn, val, fit_size, widget_size, length, nameEpn): try: picn_old = picn picn = ui.image_fit_option(picn_old, '', fit_size=fit_size, widget_size=widget_size) img = QtGui.QPixmap(picn, "1") q1="ui.label_epn_"+str(browse_cnt)+".setPixmap(img)" exec (q1) #QtWidgets.QApplication.processEvents() except Exception as err: print(err, '--917--') class GetServerEpisodeInfo(QtCore.QThread): def __init__( self, ui_widget, logr, site, opt, siteName, video_local_stream, name, ei, category, from_cache): QtCore.QThread.__init__(self) global ui, logger ui = ui_widget logger = logr self.site = site self.opt = opt self.siteName = siteName self.video_local_stream = video_local_stream self.name = name self.ei = ei self.category = category self.from_cache = from_cache def __del__(self): self.wait() def run(self): print(self.name) ui.newlistfound( self.site, self.opt, self.siteName, self.video_local_stream, self.name, self.ei, self.category, from_cache=self.from_cache) print('End') class ThreadingExample(QtCore.QThread): def __init__(self, name, logr, tmp): QtCore.QThread.__init__(self) global logger, TMPDIR self.name1 = name self.interval = 1 logger = logr TMPDIR = tmp def __del__(self): self.wait() def run(self): name = self.name1 name2 = name.replace(' ', '+') if name2 != 'NONE': url = "https://www.last.fm/search?q="+name2 logger.info(url) wiki = "" content = ccurl(url) soup = BeautifulSoup(content, 'lxml') link = soup.findAll('div', {'class':'row clearfix'}) logger.info('{0}-{1}'.format(link, 253)) name3 = "" for i in link: j = i.findAll('a') for k in j: try: url = k['href'] if '?q=' not in url: logger.info(url) break except: pass logger.info(url) if url.startswith('http'): url = url else: url = "https://www.last.fm" + url logger.info(url) img_url = url+'/+images' wiki_url = url + '/+wiki' logger.info(wiki_url) content = ccurl(wiki_url) soup = BeautifulSoup(content, 'lxml') link = soup.find('div', {'class':'wiki-content'}) if link: wiki = link.text content = ccurl(img_url) soup = BeautifulSoup(content, 'lxml') link = soup.findAll('ul', {'class':'image-list'}) img = [] for i in link: j = i.findAll('img') for k in j: l = k['src'] u1 = l.rsplit('/', 2)[0] u2 = l.split('/')[-1] u = u1 + '/770x0/'+u2 img.append(u) img = list(set(img)) logger.info(len(img)) tmp_bio = os.path.join(TMPDIR, name+'-bio.txt') write_files(tmp_bio, wiki, line_by_line=False) thumb = os.path.join(TMPDIR, name+'.jpg') if img: url = img[0] try: ccurl(url+'#'+'-o'+'#'+thumb) except Exception as err: print(err, '--623--') tmp_n = os.path.join(TMPDIR, name+'.txt') write_files(tmp_n, img, line_by_line=True) class BroadcastServer(QtCore.QThread): broadcast_signal = pyqtSignal(str) def __init__(self, ui_widget, broadcast=None): QtCore.QThread.__init__(self) global ui ui = ui_widget if broadcast: ui.broadcast_server = True self.broadcast_signal.connect(broadcast_server_signal) def __del__(self): self.wait() def run(self): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) port = str(ui.local_port_stream) print(ui.local_ip_stream, '-----ip--', ui.local_port_stream) msg = 'this is kawaii-player At: port={} https={} pc_to_pc_casting={} msg={}'.format( port, ui.https_media_server, ui.pc_to_pc_casting, ui.broadcast_message) msg = bytes(msg , 'utf-8') if ui.https_media_server: https_val = 'https' else: https_val = 'http' subnet_mask = ui.local_ip_stream.rsplit('.', 1)[0] + '.255' notify_msg = '{0}://{1}:{2} started broadcasting. Now Clients can Discover it'.format( https_val, ui.local_ip_stream, ui.local_port_stream) send_notification(notify_msg) print(subnet_mask) while ui.broadcast_server: s.sendto(msg, (subnet_mask,12345)) time.sleep(1) send_notification('Broadcasting Stopped') @pyqtSlot(str) def broadcast_server_signal(val): send_notification(val) class DiscoverServer(QtCore.QThread): discover_signal = pyqtSignal(str) clear_list = pyqtSignal(str) def __init__(self, ui_widget, start_discovery=None): QtCore.QThread.__init__(self) global ui ui = ui_widget if start_discovery: ui.discover_server = True self.discover_signal.connect(remember_server) self.clear_list.connect(clear_server_list) def __del__(self): self.wait() def run(self): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('', 12345)) s.settimeout(60) port_val = '' https_val = '' msg_val = '' if ui.discover_slaves: notifymsg = ('Started Process of Discovering. Make sure that\ Slave is broadcasting itself') else: notifymsg = 'Started Process of Discovering' notifymsg = re.sub(' +', ' ', notifymsg) send_notification(notifymsg) if ui.discover_server: self.clear_list.emit('start') while ui.discover_server or ui.discover_slaves: try: m = s.recvfrom(1024) val = str(m[0], 'utf-8') server = str(m[1][0]) casting_mode = None if val.lower().startswith('this is kawaii-player at:'): val_string = (val.split(':')[1]).strip() val_arr = val_string.split(' ') for i in val_arr: if i.startswith('port='): port_val = i.split('=')[1] elif i.startswith('https='): https_status = i.split('=')[1] if https_status == 'True': https_val = 'https' else: https_val = 'http' elif i.startswith('pc_to_pc_casting='): casting_mode = i.split('=')[1] if casting_mode == 'slave' and ui.discover_slaves: slave_address = '{}://{}:{}'.format(https_val, server, port_val) if slave_address not in ui.pc_to_pc_casting_slave_list: ui.pc_to_pc_casting_slave_list.append(slave_address) msg_val = re.search('msg=[^"]*', val_string).group() msg_val = msg_val.replace('msg=', '', 1) server_val = '{0}://{1}:{2}/\t{3}'.format( https_val, server, port_val, msg_val) if server_val not in ui.broadcast_server_list and ui.discover_server: ui.broadcast_server_list.append(server_val) self.discover_signal.emit(server_val) time.sleep(1) except Exception as e: print('timeout', e) break if not ui.broadcast_server_list and ui.discover_server: send_notification('No Server Found') self.clear_list.emit('no server') elif not ui.pc_to_pc_casting_slave_list and ui.discover_slaves: send_notification('No Slave Found') elif ui.broadcast_server_list: send_notification('Stopped Discovering: found {} servers'.format(len(ui.broadcast_server_list))) elif ui.pc_to_pc_casting_slave_list: send_notification('Stopped Discovering: found {} slaves'.format(len(ui.pc_to_pc_casting_slave_list))) @pyqtSlot(str) def remember_server(val): ui.text.setText('Found..') ui.original_path_name.append(val) ui.list1.addItem(val.split('\t')[0]) @pyqtSlot(str) def clear_server_list(val): if val == 'start': ui.text.setText('Waiting...(wait time = 60s)') elif val == 'no server': ui.text.setText('Nothing found. Try Manual Login') ui.broadcast_server_list.clear() ui.list1.clear() ui.original_path_name.clear() @pyqtSlot(str) def start_new_player_instance(command): global ui ui.infoPlay(command)