def nginx_command(self, command, conf): conf = conf.replace("\r\n", "\n").replace("\r", "\n") write_file(conf, conf_filepath) if command == 'test': data = SystemLogicCommand.execute_command_return(['nginx', '-t']) elif command == 'reload': data = SystemLogicCommand.execute_command_return( ['nginx', '-s', 'reload']) return data.split('\n')
def process_ajax(sub, req): try: if sub == 'start': ret = LogicGclone.start() return jsonify(ret) elif sub == 'stop': LogicGclone.current_data['user_stop'] = True ret = LogicGclone.kill() return jsonify(ret) elif sub == 'version': command = [ModelSetting.get('gclone_path'), 'version'] process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, bufsize=1) ret = [] with process.stdout: for line in iter(process.stdout.readline, b''): ret.append(line) process.wait() # wait for the subprocess to exit return jsonify(ret) elif sub == 'view_config': from framework.common.util import read_file data = read_file(ModelSetting.get('gclone_config_path')) return jsonify({'ret':True, 'data':data}) elif sub == 'gen_config': default = ''' [gc] type = drive scope = drive service_account_file = {first_json} service_account_file_path = {accounts_dir}/ ''' import glob accounts_dir = ModelSetting.get('path_accounts') sa_files = glob.glob(os.path.join(accounts_dir, '*.json')) if len(sa_files) == 0: ret = {'ret':False, 'log:': u'json 파일이 없습니다.'} else: first_json = os.path.join(accounts_dir, sa_files[0]) default = default.format(first_json=first_json, accounts_dir=accounts_dir) logger.debug(default) from framework.common.util import read_file, write_file config_path = ModelSetting.get('gclone_config_path') write_file(default, config_path) ret = {'ret':True, 'data':read_file(config_path)} return jsonify(ret) elif sub == 'log_reset': LogicGclone.current_data['log'] = [] return jsonify('') except Exception as e: logger.error('Exception:%s', e) logger.error(traceback.format_exc())
def process_api(self, sub, req): if sub == 'install': title = request.form['title'] script = request.form['script'] mode = request.form['mode'] import base64 script = base64.b64decode(script) logger.debug(script) script = script.split('===SCRIPT_START===')[1].split( '===SCRIPT_END===')[0].strip() script = script.replace(' ', ' ').replace('</p>', '\n').replace('<br>', '\n') script = re.sub('(<([^>]+)>)', '', script) script = script.replace('\r\n', '\n').strip() script = script + '\n' script = script.format(sjva_root=path_app_root) write_file(script, '{}/data/tmp/install.sh'.format(path_app_root)) logger.debug(script) logger.debug( os.path.exists('{}/data/tmp/install.sh'.format(path_app_root))) self.program_install(title, None, mode) return jsonify({"log": "SJVA에서 확인하세요."})
def api(sub): if sub == 'url.m3u8': try: mode = request.args.get('m') source = request.args.get('s') source_id = request.args.get('i') quality = request.args.get('q') logger.debug('m:%s, s:%s, i:%s', mode, source, source_id) action, ret = LogicKlive.get_url(source, source_id, quality, mode) #logger.debug('action:%s, url:%s', action, ret) if mode == 'plex': #new_url = '%s/klive/api/url.m3u8?m=web_play&s=%s&i=%s&q=%s' % (SystemModelSetting.get('ddns'), source, source_id, quality) new_url = '%s/klive/api/url.m3u8?m=url&s=%s&i=%s&q=%s' % (SystemModelSetting.get('ddns'), source, source_id, quality) #logger.debug(SystemModelSetting.get_bool('auth_use_apikey')) if SystemModelSetting.get_bool('auth_use_apikey'): new_url += '&apikey=%s' % SystemModelSetting.get('auth_apikey') def generate(): startTime = time.time() buffer = [] sentBurst = False if platform.system() == 'Windows': path_ffmpeg = os.path.join(path_app_root, 'bin', platform.system(), 'ffmpeg.exe') else: path_ffmpeg = 'ffmpeg' #ffmpeg_command = [path_ffmpeg, "-i", new_url, "-c", "copy", "-f", "mpegts", "-tune", "zerolatency", "pipe:stdout"] #ffmpeg_command = [path_ffmpeg, "-i", new_url, "-c:v", "copy", "-c:a", "aac", "-b:a", "128k", "-f", "mpegts", "-tune", "zerolatency", "pipe:stdout"] # 2020-12-17 by 잠자 ffmpeg_command = [path_ffmpeg, "-loglevel", "quiet", "-i", new_url, "-c:v", "copy", "-c:a", "aac", "-b:a", "128k", "-f", "mpegts", "-tune", "zerolatency", "pipe:stdout"] #logger.debug('command : %s', ffmpeg_command) process = subprocess.Popen(ffmpeg_command, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, bufsize = -1) global process_list process_list.append(process) while True: line = process.stdout.read(1024) buffer.append(line) if sentBurst is False and time.time() > startTime + 1 and len(buffer) > 0: sentBurst = True for i in range(0, len(buffer) - 2): yield buffer.pop(0) elif time.time() > startTime + 1 and len(buffer) > 0: yield buffer.pop(0) process.poll() if isinstance(process.returncode, int): if process.returncode > 0: logger.debug('FFmpeg Error :%s', process.returncode) break return Response(stream_with_context(generate()), mimetype = "video/MP2T") if action == 'redirect': return redirect(ret, code=302) elif action == 'return_after_read': logger.warning('return_after_read') data = LogicKlive.get_return_data(source, source_id, ret, mode) #logger.debug('Data len : %s', len(data)) return data, 200, {'Content-Type': 'application/vnd.apple.mpegurl'} elif action == 'return': return ret if ret == None: return if mode == 'url.m3u8': return redirect(ret, code=302) elif mode == 'lc': return ret except Exception as e: logger.error('Exception:%s', e) logger.error(traceback.format_exc()) elif sub == 'm3uall': return LogicKlive.get_m3uall() elif sub == 'm3u': data = LogicKlive.get_m3u(m3u_format=request.args.get('format'), group=request.args.get('group'), call=request.args.get('call')) if request.args.get('file') == 'true': import framework.common.util as CommonUtil basename = 'klive_custom.m3u' filename = os.path.join(path_data, 'tmp', basename) CommonUtil.write_file(data, filename) return send_file(filename, as_attachment=True, attachment_filename=basename) else: return data elif sub == 'm3utvh': return LogicKlive.get_m3u(for_tvh=True, m3u_format=request.args.get('format'), group=request.args.get('group')) elif sub == 'redirect': try: url = request.args.get('url') proxy = request.args.get('proxy') proxies = None if proxy is not None: proxy = py_urllib.unquote(proxy) proxies={"https": proxy, 'http':proxy} url = py_urllib.unquote(url) #logger.debug('REDIRECT:%s', url) #logger.warning(f"redirect : {url}") # 2021-06-03 """ res = requests.get(url, proxies=proxies) data = res.content return data, 200, {'Content-Type':res.headers['Content-Type']} """ headers = {'Connection' : 'keep-alive'} r = requests.get(url, headers=headers, stream=True, proxies=proxies) rv = Response(r.iter_content(chunk_size=1024), r.status_code, content_type=r.headers['Content-Type'], direct_passthrough=True) return rv except Exception as e: logger.error('Exception:%s', e) logger.error(traceback.format_exc()) elif sub == 'url.mpd': try: mode = request.args.get('m') source = request.args.get('s') source_id = request.args.get('i') quality = request.args.get('q') return_format = 'json' data = LogicKlive.get_play_info(source, source_id, quality, mode=mode, return_format=return_format) return jsonify(data) except Exception as e: logger.error('Exception:%s', e) logger.error(traceback.format_exc()) elif sub == 'url.strm': try: mode = request.args.get('m') source = request.args.get('s') source_id = request.args.get('i') quality = request.args.get('q') return_format = 'strm' data = LogicKlive.get_play_info(source, source_id, quality, mode=mode, return_format=return_format) #return data import framework.common.util as CommonUtil from .model import ModelCustom db_item = ModelCustom.get(source, source_id) if db_item is not None: basename = '%s.strm' % db_item.title else: basename = '%s.strm' % source_id filename = os.path.join(path_data, 'tmp', basename) CommonUtil.write_file(data, filename) return send_file(filename, as_attachment=True, attachment_filename=basename) #return data except Exception as e: logger.error('Exception:%s', e) logger.error(traceback.format_exc()) elif sub == 'sinaplayer': data = LogicKlive.get_m3u_for_sinaplayer() return data
def make_episode_info(self): try: url = 'https://www.jetcloud-list.cc/kr/episode/' + self.info['va'] text = requests.get(url, headers=headers).text match = re.compile('src\=\"(?P<video_url>http.*?\.m3u8)').search(text) if match: tmp = match.group('video_url') # 2020-11-06 master.m3u8 cloudflare가 막음. 화질별은 아직 안막음. #m3u8 = requests.get(tmp, headers=LogicAni365.current_headers).text #for t in m3u8.split('\n'): # if t.find('m3u8') != -1: # self.url = tmp.replace('master.m3u8', t.strip()) # self.quality = t.split('.m3u8')[0] m3u8_text = requests.get(tmp, headers=headers).text.strip() self.url = m3u8_text.split('\n')[-1].strip() logger.debug(self.url) self.quality = self.url.split('/')[-1].split('.')[0] """ logger.debug(tmp) master = tmp.replace('https://', '').split('/') logger.debug(master) master[1] += 's' url_1080 = copy.deepcopy(master) url_1080.insert(3, '1080') url_1080[-1] = url_1080[-1].replace('master', '1080') tmp = 'https://' + '/'.join(url_1080) res = requests.get(tmp, headers=LogicAni365.current_headers) if res.status_code == 200: self.url = tmp self.quality = '1080' else: url_720 = copy.deepcopy(master) url_720.insert(3, '720') url_720[-1] = url_1080[-1].replace('master', '720') self.url = 'https://' + '/'.join(url_720) self.quality = '720' """ #https://www.jetcloud-list.cc/getfiles/4yekl4kluyjldcefts7wuNtfQ7tRhoqyywN08Qb1bbg5ja32gv/1080/9cfea65b412beb6d02cda008326ec9d2/1080.m3u8 #https://www.jetcloud-list.cc/getfiles/uwcngQuksgs5fka9qe2eg7tPdkhNejchht6xija5dcqtafthjj/1080/9cfea65b412beb6d02cda008326ec9d2/1080.m3u8 match = re.compile(r'src\=\"(?P<vtt_url>http.*?kr.vtt)').search(text) if match: self.vtt = u'%s' % match.group('vtt_url') match = re.compile(r'(?P<title>.*?)\s*((?P<season>\d+)%s)?\s*((?P<epi_no>\d+)%s)' % (u'기', u'화')).search(self.info['title']) if match: self.content_title = match.group('title').strip() if 'season' in match.groupdict() and match.group('season') is not None: self.season = int(match.group('season')) epi_no = int(match.group('epi_no')) ret = '%s.S%sE%s.%s-SA.mp4' % (self.content_title, '0%s' % self.season if self.season < 10 else self.season, '0%s' % epi_no if epi_no < 10 else epi_no, self.quality) else: self.content_title = self.info['title'] P.logger.debug('NOT MATCH') ret = '%s.720p-SA.mp4' % self.info['title'] self.filename = Util.change_text_for_use_filename(ret) self.savepath = P.ModelSetting.get('ani365_download_path') if P.ModelSetting.get_bool('ani365_auto_make_folder'): if self.info['day'].find(u'완결') != -1: folder_name = '%s %s' % (P.ModelSetting.get('ani365_finished_insert'), self.content_title) else: folder_name = self.content_title folder_name = Util.change_text_for_use_filename ( folder_name.strip() ) self.savepath = os.path.join(self.savepath, folder_name) if P.ModelSetting.get_bool('ani365_auto_make_season_folder'): self.savepath = os.path.join(self.savepath, 'Season %s' % int(self.season)) self.filepath = os.path.join(self.savepath, self.filename) if not os.path.exists(self.savepath): os.makedirs(self.savepath) from framework.common.util import write_file, convert_vtt_to_srt srt_filepath = os.path.join(self.savepath, self.filename.replace('.mp4', '.ko.srt')) if not os.path.exists(srt_filepath): vtt_data = requests.get(self.vtt, headers=LogicAni365.current_headers).text srt_data = convert_vtt_to_srt(vtt_data) write_file(srt_data, srt_filepath) self.headers = LogicAni365.current_headers except Exception as e: P.logger.error('Exception:%s', e) P.logger.error(traceback.format_exc())
def __make_rclone_conf(config_path, rclone_upload_remote, folder_id): try: #logger.debug(rclone_upload_remote) from framework.common.util import read_file if os.path.exists(config_path): rclone_info = read_file(config_path) from framework import path_data import time filename = '%s.conf' % (str(time.time()).split('.')[0]) conf_filepath = os.path.join(path_data, 'tmp', filename) #logger.debug('conf_filepath:%s', conf_filepath) #logger.debug(rclone_info) start = -1 dest_remote = None match = None first_rclone_info = None while True: start = rclone_info.find('[', start + 1) if start == -1: break next_start = rclone_info.find('[', start + 1) if next_start == -1: dest_remote = rclone_info[start:] else: dest_remote = rclone_info[start:next_start] #dest_remote = dest_remote.replace('team_drive', 'team_drive_dummy') #logger.debug(dest_remote) if first_rclone_info is None and dest_remote.find( 'access_token') != -1: first_rclone_info = dest_remote import re match = re.compile(r'\[(?P<remote_name>.*?)\]').search( dest_remote.strip()) if match.group('remote_name') == rclone_upload_remote: break else: dest_remote = None match = None #공유드라이브는 삭제 #dest_remote : 찾은 리모트 #rclone_info : 서버리모트가 될 리모트 if rclone_upload_remote is not None: if dest_remote is None: raise Exception('cannot find remote_name') else: # 로컬등 구글게 아니면? #if dest_remote.find('access_token') == -1: if dest_remote.find('type = drive') == -1: if first_rclone_info is not None: src_remote_ready = first_rclone_info else: raise Exception('cannot find google remote_name') else: # 정상인 경우 pass src_remote_ready = dest_remote else: src_remote_ready = first_rclone_info src_remote_ready = src_remote_ready.replace( 'team_drive', 'team_drive_dummy') # gclone이나 로컬이라면 rclone match = re.compile(r'\[(?P<remote_name>.*?)\]').search( src_remote_ready.strip()) server_rclone = src_remote_ready.replace( '[%s]' % match.group('remote_name'), '[%s]' % REMOTE_NAME_SJVA_SHARE_TEMP) server_rclone += '\nroot_folder_id = %s' % folder_id filedata = '%s\n\n%s\n' % (dest_remote, server_rclone) #logger.debug(filedata) import framework.common.util as CommonUtil CommonUtil.write_file(filedata, conf_filepath) return conf_filepath except Exception as exception: logger.error('Exception:%s', exception) logger.error(traceback.format_exc())