Пример #1
0
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
Пример #2
0
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
Пример #3
0
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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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