def is_server(): if os.path.isfile(ap.dl_server_dir + "1"): cm.clear_path(ap.dl_server_dir + "1") cm.queue_append(ap.dl_server_dir + "2") return APP_SERVER_2 else: cm.clear_path(ap.dl_server_dir + "2") cm.queue_append(ap.dl_server_dir + "1") return APP_SERVER_1
def search(youtube_id): """get movie from youtube get movie from YouTube iTag 22 (720p / mp4) or iTag 18 (360p / mp4) Args: youtube_id (str): user input youtube_id Returns: movie_path (str): movie save path movie_title (str): movie title movie_length (str): movie length movie_thumbnail (str): movie thumbnail url status (str): error status while get movie """ # add dl ongoing queue dl_ongoing_path = ap.dl_ongoing_dir + str(youtube_id) cm.queue_append(dl_ongoing_path) youtube_url = "https://www.youtube.com/watch?v=" + youtube_id try: # add dl pending queue dl_pending_path = ap.dl_pending_dir + "pending" cm.queue_append(dl_pending_path) yt = YouTube(youtube_url) except: cm.clear_path(dl_ongoing_path) return None, None, None, None, state.TMP_CANT_GET_HD movie_thumbnail = yt.thumbnail_url movie_length = yt.length if int(movie_length) > MOVIE_LENGTH_MAX: cm.clear_path(dl_ongoing_path) return None, None, None, None, state.ERR_BAD_LENGTH status = state.DONE stream = yt.streams.get_by_itag(22) if stream is None: status = state.TMP_DONE_IN_SD stream = yt.streams.get_by_itag(18) if stream is None: cm.clear_path(dl_ongoing_path) return None, None, None, None, state.ERR_BAD_RESOLUTION movie_title = stream.title movie_name = tm.time() movie_path = stream.download(ap.stream_dir, str(movie_name)) cm.clear_path(dl_ongoing_path) return movie_path, movie_title, movie_length, movie_thumbnail, status
def rest_analyze(): status = el.DONE rest_result = {} ret = {} url = "" if request.method == "POST": if "Url" not in request.form: status = el.ERR_BAD_REQ ret["result"] = rest_result ret["msg"] = el.get_error_message(status) ret["status"] = status return jsonify(ret) else: url = request.form["Url"] elif request.method == "GET": if "Url" not in request.args: status = el.ERR_BAD_REQ ret["result"] = rest_result ret["msg"] = el.get_error_message(status) ret["status"] = status return jsonify(ret) else: url = request.args.get("Url") # キャッシュ確認 youtube_id = an.get_youtube_id(url) if youtube_id is False: # 不正なurlの場合 status = el.ERR_BAD_URL else: # 正常なurlの場合 cache = cm.cache_check(youtube_id) if cache is not False: # キャッシュ有りの場合 # キャッシュを返信 title, time_line, time_data, total_damage, debuff_value, past_status = cache if past_status // 100 == 2: rest_result = get_rest_result(title, time_line, time_data, total_damage, debuff_value) ret["result"] = rest_result ret["msg"] = el.get_error_message(past_status) ret["status"] = past_status return jsonify(ret) elif (past_status // 100) == 3: pass else: ret["result"] = rest_result ret["msg"] = el.get_error_message(past_status) ret["status"] = past_status return jsonify(ret) # start analyze # 既にキューに登録されているか確認 queue_path = queue_dir + str(youtube_id) pending_path = pending_dir + str(youtube_id) queued = os.path.exists(queue_path) if queued: # 既に解析中の場合 while True: # キューが消えるまで監視 # 暫定的実装 # 監視中にキューが30分以上残置されているのを見つけると削除する try: now = datetime.date.today() # 現在の時刻を取得 timestamp = datetime.date.fromtimestamp(int(os.path.getmtime(queue_path))) if (now - timestamp).seconds >= 30 * 60: # 30分経過してたら削除 cm.clear_path(queue_path) cm.clear_path(pending_path) except FileNotFoundError: pass queued = os.path.exists(queue_path) if queued: tm.sleep(1) continue else: # 既に開始されている解析が完了したら、そのキャッシュJSONを返す cache = cm.cache_check(youtube_id) if cache is not False: title, time_line, time_data, total_damage, debuff_value, past_status = cache if past_status // 100 == 2 or past_status // 100 == 3: rest_result = get_rest_result(title, time_line, time_data, total_damage, debuff_value) status = past_status break else: # キャッシュ未生成の場合 # キャッシュを書き出してから解析キューから削除されるため、本来起こり得ないはずのエラー status = el.ERR_UNEXPECTED break else: # 既に解析中ではない場合 # 解析キューに登録 cm.queue_append(queue_path) # キューが回ってきたか確認し、来たら解析実行 while True: if not cm.is_pending_exists() and cm.is_queue_current(queue_path): # pendingに登録 pending_path = pending_dir + str(youtube_id) cm.pending_append(pending_path) # youtube動画検索/検証 path, title, length, thumbnail, url_result = an.search(youtube_id) status = url_result if url_result // 100 == 4: cm.save_cache(youtube_id, title, False, False, False, False, url_result) elif url_result == el.ERR_CANT_GET_HD: pass else: # TL解析 time_line, time_data, total_damage, debuff_value, analyze_result = an.analyze_movie(path) status = analyze_result # キャッシュ保存 cm.save_cache(youtube_id, title, time_line, False, total_damage, debuff_value, status) if analyze_result is el.DONE: # 解析が正常終了ならば結果を格納 rest_result = get_rest_result(title, time_line, time_data, total_damage, debuff_value) cm.clear_path(queue_path) cm.clear_path(pending_path) break tm.sleep(1) ret["result"] = rest_result ret["msg"] = el.get_error_message(status) ret["status"] = status return jsonify(ret)
def rest_analyze(): status = state.ERR_REQ_UNEXPECTED is_parent = False rest_result = {} ret = {} url = "" raw_url = "" token = "" # clear old movie if passed 2 hours cm.tmp_movie_clear() if request.method == "POST": if "Url" not in request.form: status = state.ERR_BAD_REQ ret["result"] = rest_result ret["msg"] = state.get_error_message(status) ret["status"] = status return jsonify(ret) else: raw_url = request.form["Url"] if SERVER_TOKEN_AUTH and "Token" not in request.form: status = state.ERR_BAD_REQ ret["result"] = rest_result ret["msg"] = state.get_error_message(status) ret["status"] = status return jsonify(ret) else: token = request.form["Token"] elif request.method == "GET": if "Url" not in request.args: status = state.ERR_BAD_REQ ret["result"] = rest_result ret["msg"] = state.get_error_message(status) ret["status"] = status return jsonify(ret) else: raw_url = request.args.get("Url") if SERVER_TOKEN_AUTH and "Token" not in request.args: status = state.ERR_BAD_REQ ret["result"] = rest_result ret["msg"] = state.get_error_message(status) ret["status"] = status return jsonify(ret) else: token = request.args.get("Token") try: # tokenの確認とロード if SERVER_TOKEN_AUTH: json.load(open(token_dir + urllib.parse.quote(token) + ".json")) except FileNotFoundError: status = state.ERR_BAD_TOKEN ret["result"] = rest_result ret["msg"] = state.get_error_message(status) ret["status"] = status return jsonify(ret) # URL抽出 tmp_group = re.search('(?:https?://)?(?P<host>.*?)(?:[:#?/@]|$)', raw_url) if tmp_group: host = tmp_group.group('host') if host == "www.youtube.com" or host == "youtu.be": url = raw_url # キャッシュ確認 youtube_id = al.get_youtube_id(url) queue_path = queue_dir + str(youtube_id) pending_path = pending_dir + str(youtube_id) dl_queue_path = dl_queue_dir + str(youtube_id) if youtube_id is False: # 不正なurlの場合 status = state.ERR_BAD_URL else: # 正常なurlの場合 cache = cm.cache_check(youtube_id) if cache is not False: # キャッシュ有りの場合 # キャッシュを返信 title, time_line, time_line_enemy, time_data, total_damage, debuff_value, past_status = cache if past_status % 100 // 10 == 0: rest_result = get_rest_result(title, time_line, time_line_enemy, time_data, total_damage, debuff_value) ret["result"] = rest_result ret["msg"] = state.get_error_message(past_status) ret["status"] = past_status return jsonify(ret) else: ret["result"] = rest_result ret["msg"] = state.get_error_message(past_status) ret["status"] = past_status return jsonify(ret) if SERVER_ERROR_STATE: ret["result"] = rest_result ret["msg"] = state.get_error_message(state.ERR_SERVICE_UNAVAILABLE) ret["status"] = state.ERR_SERVICE_UNAVAILABLE return jsonify(ret) # start analyze # 既にキューに登録されているか確認 queued = os.path.exists(queue_path) if not queued: # 既に解析中ではない場合、解析キューに登録 cm.queue_append(queue_path) # キューが回ってきたか確認し、来たら解析実行 while True: cm.watchdog(youtube_id, is_parent, 1800, state.TMP_QUEUE_TIMEOUT) rest_pending = cm.is_path_exists(pending_path) rest_queue = cm.is_path_due(queue_path) web_download = cm.is_path_exists(dl_queue_path) if not rest_pending and rest_queue and not web_download: if cm.is_pending_download(15): # check pending download if not MULTI_SERVER: analyzer_path = f'python exec_analyze.py {url}' cm.pending_append(pending_path) subprocess.Popen(analyzer_path.split()) is_parent = True else: analyzer_path = f'python multi_exec_analyze.py {url}' cm.pending_append(pending_path) subprocess.Popen(analyzer_path.split()) is_parent = True break tm.sleep(1) while True: # キューが消えるまで監視 queued = os.path.exists(queue_path) if queued: if is_parent: # 親ならばpendingを監視 cm.watchdog(youtube_id, is_parent, 300, state.TMP_ANALYZE_TIMEOUT) else: # 子ならばqueueを監視 cm.watchdog(youtube_id, is_parent, 2160, state.TMP_QUEUE_TIMEOUT) tm.sleep(1) continue else: # 解析が完了したら、そのキャッシュJSONを返す cache = cm.queue_cache_check(youtube_id) if cache is not False: title, time_line, time_line_enemy, time_data, total_damage, debuff_value, past_status = cache rest_result = get_rest_result(title, time_line, time_line_enemy, time_data, total_damage, debuff_value) status = past_status break else: # キャッシュ未生成の場合 # キャッシュを書き出してから解析キューから削除されるため、本来起こり得ないはずのエラー status = state.TMP_UNEXPECTED break ret["result"] = rest_result ret["msg"] = state.get_error_message(status) ret["status"] = status return jsonify(ret)
def index(): if request.method == "POST": url = (request.form["Url"]) # urlからid部分の抽出 youtube_id = al.get_youtube_id(url) if youtube_id is False: error = state.get_error_message(state.ERR_BAD_URL) return render_template("index.html", error=error) cache = cm.cache_check(youtube_id) if cache is not False: title, time_line, time_line_enemy, time_data, total_damage, debuff_value, past_status = cache if past_status % 100 // 10 == 0: debuff_dict, data_txt, data_url, total_damage = get_web_txt( youtube_id, title, time_line, debuff_value, total_damage) return render_template("result.html", title=title, timeLine=time_line, timeLineEnemy=time_line_enemy, timeData=time_data, totalDamage=total_damage, debuffDict=debuff_dict, data_txt=data_txt, data_url=data_url) else: error = state.get_error_message(past_status) return render_template("index.html", error=error) if SERVER_ERROR_STATE: error = state.get_error_message(state.ERR_SERVICE_UNAVAILABLE) return render_template("index.html", error=error) # start download dl_queue_path = dl_queue_dir + str(youtube_id) dl_ongoing_path = dl_ongoing_dir + str(youtube_id) # 既にキューに登録されているか確認 queued = os.path.exists(dl_queue_path) if not queued: # 既にダウンロード待機中ではない場合、ダウンロード待機キューに登録 cm.queue_append(dl_queue_path) # キューが回ってきたか確認し、来たらダウンロード実行 while True: if not cm.is_path_exists(dl_ongoing_path) and cm.is_path_due( dl_queue_path): if cm.is_pending_download(15): # check pending download break timeout = cm.watchdog_download(youtube_id, 300) # 5分間タイムアウト監視 if timeout: cm.clear_path(dl_queue_path) error = "動画の解析待ちでタイムアウトが発生しました。再実行をお願いします。" return render_template("index.html", error=error) tm.sleep(1) else: # ダウンロード待機中の場合エラーメッセージ表示 cm.clear_path(dl_queue_path) error = "同一の動画が解析中です。時間を置いて再実行をお願いします。" return render_template("index.html", error=error) path, title, length, thumbnail, url_result = al.search(youtube_id) cm.clear_path(dl_queue_path) if url_result % 100 // 10 == 2: error = state.get_error_message(url_result) cm.save_cache(youtube_id, title, False, False, False, False, False, url_result) return render_template("index.html", error=error) session["path"] = path session["title"] = title session["youtube_id"] = youtube_id length = int(int(length) / 8) + 3 return render_template("analyze.html", title=title, length=length, thumbnail=thumbnail) elif request.method == "GET": if "v" in request.args: # ?v=YoutubeID 形式のGETであればリザルト返却 youtube_id = request.args.get("v") if re.fullmatch(r"^([a-zA-Z0-9_-]{11})$", youtube_id): cache = cm.cache_check(youtube_id) if cache is not False: title, time_line, time_line_enemy, time_data, total_damage, debuff_value, past_status = cache if past_status % 100 // 10 == 0: debuff_dict, data_txt, data_url, total_damage = get_web_txt( youtube_id, title, time_line, debuff_value, total_damage) return render_template("result.html", title=title, timeLine=time_line, timeLineEnemy=time_line_enemy, timeData=time_data, totalDamage=total_damage, debuffDict=debuff_dict, data_txt=data_txt, data_url=data_url) else: error = state.get_error_message(past_status) return render_template("index.html", error=error) else: # キャッシュが存在しない場合は解析 if SERVER_ERROR_STATE: error = state.get_error_message( state.ERR_SERVICE_UNAVAILABLE) return render_template("index.html", error=error) # start download dl_queue_path = dl_queue_dir + str(youtube_id) dl_ongoing_path = dl_ongoing_dir + str(youtube_id) # 既にキューに登録されているか確認 queued = os.path.exists(dl_queue_path) if not queued: # 既にダウンロード待機中ではない場合、ダウンロード待機キューに登録 cm.queue_append(dl_queue_path) # キューが回ってきたか確認し、来たらダウンロード実行 while True: if not cm.is_path_exists( dl_ongoing_path) and cm.is_path_due( dl_queue_path): if cm.is_pending_download( 15): # check pending download break timeout = cm.watchdog_download(youtube_id, 300) # 5分間タイムアウト監視 if timeout: cm.clear_path(dl_queue_path) error = "動画の解析待ちでタイムアウトが発生しました。再実行をお願いします。" return render_template("index.html", error=error) tm.sleep(1) else: # ダウンロード待機中の場合エラーメッセージ表示 cm.clear_path(dl_queue_path) error = "同一の動画が解析中です。時間を置いて再実行をお願いします。" return render_template("index.html", error=error) path, title, length, thumbnail, url_result = al.search( youtube_id) cm.clear_path(dl_queue_path) if url_result % 100 // 10 == 2: error = state.get_error_message(url_result) cm.save_cache(youtube_id, title, False, False, False, False, False, url_result) return render_template("index.html", error=error) session["path"] = path session["title"] = title session["youtube_id"] = youtube_id length = int(int(length) / 8) + 3 return render_template("analyze.html", title=title, length=length, thumbnail=thumbnail) else: # prilog.jp/(YoutubeID)に該当しないリクエスト error = "不正なリクエストです" return render_template("index.html", error=error) else: path = session.get("path") session.pop("path", None) session.pop("title", None) session.pop("youtube_id", None) error = None if str(path).isdecimal(): error = state.get_error_message(path) elif path is not None: cm.clear_path(path) return render_template("index.html", error=error)
def search(youtube_id): """get movie from youtube get movie from YouTube iTag 22 (720p / mp4) or iTag 18 (360p / mp4) Args: youtube_id (str): user input youtube_id Returns: movie_path (str): movie save path movie_title (str): movie title movie_length (str): movie length movie_thumbnail (str): movie thumbnail url status (str): error status while get movie """ # add dl ongoing queue dl_ongoing_path = ap.dl_ongoing_dir + str(youtube_id) cm.queue_append(dl_ongoing_path) youtube_url = "https://www.youtube.com/watch?v=" + youtube_id try: # add dl pending queue dl_pending_path = ap.dl_pending_dir + "pending" cm.queue_append(dl_pending_path) yt = YouTube(youtube_url) except KeyError as e: # cant get movie by status ret = state.ERR_PERM_UNEXPECTED error = e.args[0] if error == "cipher": ret = state.ERR_COPYRIGHTED_CONTENT elif error == "adaptiveFormats": ret = state.TMP_CANT_GET_HD elif error == "formats": ret = state.ERR_UNAVAILABLE_CONTENT cm.clear_path(dl_ongoing_path) return None, None, None, None, ret except exceptions.RegexMatchError: # cant get movie by private or deleted cm.clear_path(dl_ongoing_path) return None, None, None, None, state.TMP_CANT_GET_HD except: # cant get movie by other reason cm.clear_path(dl_ongoing_path) return None, None, None, None, state.TMP_CANT_GET_HD movie_thumbnail = yt.thumbnail_url movie_length = yt.length if int(movie_length) > MOVIE_LENGTH_MAX: cm.clear_path(dl_ongoing_path) return None, None, None, None, state.ERR_BAD_LENGTH status = state.DONE stream = yt.streams.get_by_itag(22) if stream is None: status = state.TMP_DONE_IN_SD stream = yt.streams.get_by_itag(18) if stream is None: cm.clear_path(dl_ongoing_path) return None, None, None, None, state.ERR_BAD_RESOLUTION movie_title = stream.title movie_name = tm.time() movie_path = stream.download(ap.stream_dir, str(movie_name)) cm.clear_path(dl_ongoing_path) return movie_path, movie_title, movie_length, movie_thumbnail, status