def fetch_anime_data(): if request.method == "POST": anime_id = request.json["animeId"] session_id = request.json["sessionID"] user = User.query.filter(User.session_id == session_id).first() if user is not None: anime = (db.session.query(AnimeData).filter( AnimeData.anime_id == anime_id).first()) if anime is None: response_data = {"animes": []} else: response_data = { "animes": [{ "id": anime.anime_id, "title": anime.title, "image": img_encode(anime.image), "description": anime.description, "year": anime.year, "genre": anime.genre.split(), "company": anime.company, }] } return jsonify(response_data) else: return redirect(ENV_VALUES["APP_URL"])
def fetch_recent_user_data(): if request.method == "POST": image_num = request.json["num"] session_id = request.json["sessionID"] user = User.query.filter(User.session_id == session_id).first() if user is not None: # recommendedの日付データを見て新しい順に持ってくれば良い. # recommendedとAnimeDataをanime_idでjoinして, user_idを指定して時刻順にとってきて数の上限を設定する. past_data = (db.session.query(Recommended, AnimeData).join( Recommended, AnimeData.anime_id == Recommended.anime_id).filter( Recommended.user_id == user.user_id).order_by( desc(Recommended.updated_at)).limit( int(image_num)).all()) if past_data is None: response_data = {"animes": []} else: # print([data[1].anime_id for data in past_data]) # 各データのimageプロパティから画像をbase64でエンコードしたものを辞書にして返す. response_data = { "animes": [{ "image": img_encode(data[1].image), "id": data[0].anime_id, } for data in past_data] } return jsonify(response_data) else: return redirect(ENV_VALUES["APP_URL"])
def fetch_random_anime_data(): if request.method == "POST": # テスト用クエリ(これをターミナルで打ち込むとpostでjsonが送信されます. データベースにも反映されるはずです) # curl http://localhost:5000//app/recs -X POST -H "Content-Type: application/json" --data '{"num": "5", "sessionID": "value", "animeId": [4,7,8,9,10]}' image_num = request.json['num'] session_id = request.json['sessionID'] anime_id_buffer = request.json['animeId'] # テストするときはパラメータが無いので他で適当にfilter user = User.query.filter(User.session_id == session_id).first() # image_num = "5" # user = User.query.filter(User.name == "Kw_I_KU").first() if user is not None: lu_data = ( db.session.query(LikeUnlike) .filter(LikeUnlike.user_id == user.user_id) .all() ) past_animes = [lu.anime_id for lu in lu_data] + anime_id_buffer past_animes = list(set(past_animes)) # 過去に表示したことがあるものを含まないものからimage_num個に制限してとってくる animes = ( db.session.query(AnimeData) .filter(AnimeData.anime_id.notin_(past_animes)) .limit(int(image_num)) .all() ) response_data = { "animes": [ { "id": anime.anime_id, "title": anime.title, "image": img_encode(anime.image), # 画像をbase64で返す "description": anime.description, "year": anime.year, "genre": anime.genre.split(), "company": anime.company, } for anime in animes ] } return jsonify(response_data) else: return redirect(ENV_VALUES['APP_URL'])
def anime_results(): if request.method == "POST": # テスト用クエリ(これをターミナルで打ち込むとpostでjsonが送信されます. データベースにも反映されるはずです) # curl http://localhost:5000/app/rslts -X\ # POST -H "Content-Type: application/json"\ # --data '{"sessionID": "value", "animes": [{"animeId": "4", "like": "0"},\ # {"animeId": "5", "like": "2"}]}' session_id = request.json["sessionID"] request_body = request.json["animes"] # 送られてきたアニメidとstatusのリストを並べた二次元リストに展開しておく. all_ul_data = [[int(anime["animeId"]), int(anime["like"])] for anime in request_body] # テストするときはパラメータが無いので他で適当にfilter user = User.query.filter(User.session_id == session_id).first() # user = User.query.filter(User.name == "Kw_I_KU").first() if user is not None: try: for ul_data in all_ul_data: # like_unlikeの登録をする. 過去に同じuserとanime_idに対して登録があれば, それを更新する. past_ul = (LikeUnlike.query.filter( LikeUnlike.user_id == user.user_id).filter( LikeUnlike.anime_id == ul_data[0]).first()) if past_ul is not None: # 過去に登録されたものがあれば更新 past_ul.status = ul_data[1] else: # Noneなら追加 like_unlike = LikeUnlike( user_id=user.user_id, anime_id=ul_data[0], status=ul_data[1], ) db.session.add(like_unlike) db.session.commit() # 登録が終わったら今回受け取った情報でlike以上のものを一つ選び、レコメンドアルゴリズムに渡す. # like以上が一つでもあるならsuperlikeなものを探してそちらを優先する. なければlikeを取得, なければempty. like_anime_data = [ anime_data[0] for anime_data in all_ul_data if anime_data[1] > 0 ] if len(like_anime_data) > 0: superlike_anime_data = [ anime_data[0] for anime_data in all_ul_data if anime_data[1] == 2 ] if len(superlike_anime_data) > 0: like_anime_id = superlike_anime_data[0] else: like_anime_id = like_anime_data[0] else: raise Exception("like_anime_data is empty") # 今までにlike/unlikeを押したことのある全てのanime_idを取得する. 渡すとき0-indexにしたいので-1しておく. past_ul_data = LikeUnlike.query.filter( LikeUnlike.user_id == user.user_id).all() past_ul_list = [data.anime_id - 1 for data in past_ul_data] # 今はリストのargが返ってくるので+1してアニメidに直す. recommend = collaborative_filtering( like_anime_id, past_ul_list) + 1 # recommendがidなので、その情報を返す. 一つだけとってくる anime = (db.session.query(AnimeData).filter( AnimeData.anime_id == recommend).first()) # 該当アニメがないなら例外でエラー if anime is None: raise Exception("anime data not found") # recommendedに登録する. 既存なら何もしない. past_recommend = (Recommended.query.filter( Recommended.user_id == user.user_id).filter( Recommended.anime_id == recommend).first()) if past_recommend is None: # Noneなら追加 recommended_anime = Recommended(user_id=user.user_id, anime_id=recommend) db.session.add(recommended_anime) db.session.commit() response_data = { "animes": [{ "id": anime.anime_id, "title": anime.title, "image": img_encode(anime.image), "description": anime.description, "year": anime.year, "genre": anime.genre.split(), "company": anime.company, }] } return jsonify(response_data) except Exception as e: # 例外を受け取ったらRecommendedの直近を返すことにする. print(e) anime = (db.session.query(Recommended, AnimeData).join( Recommended, AnimeData.anime_id == Recommended.anime_id).filter( Recommended.user_id == user.user_id).order_by( desc(Recommended.updated_at)).first()[1]) if anime is None: response_data = {"animes": []} else: response_data = { "animes": [{ "id": anime.anime_id, "title": anime.title, "image": img_encode(anime.image), "description": anime.description, "year": anime.year, "genre": anime.genre.split(), "company": anime.company, }] } return jsonify(response_data) else: return redirect(ENV_VALUES["APP_URL"]) pass