Example #1
0
 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')
Example #2
0
    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())
Example #3
0
 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에서 확인하세요."})
Example #4
0
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
Example #5
0
    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())
Example #6
0
    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())