예제 #1
0
    def recommends(cls, request):
        tracks = []
        pa = ParameterAdapter()
        limit = 10  # todo:get limit by parameter
        response = []

        # get request parameters
        request_body = None
        if request.method == "GET":
            request_body = list(request.GET.dict().keys())[0]
        else:
            request_body = request.body.decode("utf-8")

        posted = json.loads(request_body)
        posted_parameters = {} if not "parameters" in posted else posted["parameters"]

        # process by methods
        if request.method == "GET":
            # initialize when get
            SessionManager.set_session(request, SessionManager.CRITICIZE_SESSION, [])
            SessionManager.set_session(request, SessionManager.TRACK_SESSION, [])

            parameters = pa.request_to_parameters(TrackCriticizeType.Parameter, None, posted_parameters)
            tracks = cls.get_scored_tracks(parameters, None, [])

        else:
            track_id = posted["track_id"]
            criticize_type = TrackCriticizeType(posted["criticize_type"])
            track = cls.__get_track(track_id, tracks)
            tracks = cls.__get_session_tracks(request)  # get from session

            parameters = pa.request_to_parameters(criticize_type, track, posted_parameters)
            history = cls.__get_session_history(request)

            # merge history and make parameter
            parameters = ParameterAdapter.merge_parameters(history + [parameters])

            if criticize_type == TrackCriticizeType.Like:
                tracks = cls.get_favorite_tracks(parameters, track, tracks)
            else:
                tracks = cls.get_scored_tracks(parameters, track, tracks)

        if len(tracks) > 0:
            # to dictionary
            serialized_evaluated = [{"score": s.score, "item": s.item.to_dict(), "score_detail": s.score_detail} for s in tracks]

            # store to session
            SessionManager.set_session(request, SessionManager.TRACK_SESSION, [s["item"] for s in serialized_evaluated])
            SessionManager.add_session(request, SessionManager.CRITICIZE_SESSION, [p.to_dict() for p in parameters])

            if limit > 0:
                serialized_evaluated = serialized_evaluated[:limit]

            response = serialized_evaluated

        return HttpResponse(json.dumps(response), content_type="application/json")
예제 #2
0
    def test_criticize_by_parameter(self):
        pa = ParameterAdapter()
        selected_track = random.sample(self.tracks, 1)[0]

        # by parameter
        criticize_type = TrackCriticizeType.Parameter
        post_parameters = {"bpm": "123"}  # dummy bpm value
        parameters = pa.request_to_parameters(criticize_type, selected_track, post_parameters)

        print(map(lambda p: p.__str__(), parameters))

        scored = RecommendApi.get_scored_tracks(parameters, selected_track, self.tracks)
        print("tracks: {0}".format(len(scored)))
        self.print_tracks(map(lambda s: s.item, scored[:10]))
예제 #3
0
    def test_criticize_by_pattern(self):
        pa = ParameterAdapter()
        selected_track = random.sample(self.tracks, 1)[0]

        # by parameter
        criticize_type = TrackCriticizeType.Pattern
        evaluator = Track.make_evaluator()
        criticize_patterns = evaluator.make_pattern(self.tracks, selected_track)

        pattern = random.sample(criticize_patterns, 1)[0]
        post_parameters = {"pattern": pattern.pattern}
        parameters = pa.request_to_parameters(criticize_type, selected_track, post_parameters)

        print(map(lambda p: p.__str__(), parameters))

        scored = RecommendApi.get_scored_tracks(parameters, selected_track, self.tracks)
        print("tracks: {0}".format(len(scored)))
        self.print_tracks(map(lambda s: s.item, scored[:10]))
예제 #4
0
    def get_scored_tracks(cls, parameters, track, initial_tracks):
        tracks = []
        trial_count = 0
        finder = Track()
        base_track = track
        pa = ParameterAdapter()
        conditions = pa.parameters_to_conditions(parameters)

        while trial_count < RecommendApi.TRACK_TRIAL_LIMIT and len(tracks) <= RecommendApi.TRACK_COUNT_BASE:
            try:
                # get tracks by criticizes
                if len(tracks) > 0:
                    conditions["offset"] = len(tracks)

                if trial_count == 0:
                    tracks += initial_tracks

                new_tracks = finder.find(conditions)
                tracks += list(filter(lambda t: t.id not in [t.id for t in tracks], new_tracks))

                # filter by inputed parameters
                if track:
                    tracks = list(filter(lambda t: pa.filter_by_parameters(parameters, track, t), tracks))

            except HTTPError as ex:
                    pass

            trial_count += 1
            sleep(0.5)

        scored = tracks
        if len(tracks) > 0:
            if track is None:
                base_track = tracks[0]

            evaluator = Track.make_evaluator(TrackCriticizePattern)
            scored = evaluator.calc_score(tracks, base_track)

        scored = scored[:RecommendApi.TRACK_COUNT_BASE]

        return scored
예제 #5
0
    def get_favorite_tracks(cls, parameters, track, initial_tracks):
        if track is None:
            Exception("If getting favorite, you have to set track parameter")

        tracks = []
        favoriters = []
        trial_count = 0
        pa = ParameterAdapter()
        user_evaluator = User.make_evaluator()

        while trial_count < RecommendApi.TRACK_TRIAL_LIMIT and len(tracks) <= RecommendApi.TRACK_COUNT_BASE:
            try:
                # get tracks by criticizes
                if trial_count == 0:
                    favoriters = track.get_favoriters()
                    if len(favoriters) > 0:
                        favoriters = user_evaluator.calc_score(favoriters, favoriters[0])
                    else:
                        break

                if len(favoriters) > trial_count:
                    new_tracks = favoriters[trial_count].item.get_favorites()
                    tracks += list(filter(lambda t: t.id not in [t.id for t in tracks], new_tracks))
                    tracks = list(filter(lambda t: pa.filter_by_parameters(parameters, track, t), tracks))

            except HTTPError as ex:
                pass

            trial_count += 1
            sleep(0.5)

        scored = []
        if len(tracks) > 0:
            evaluator = Track.make_evaluator(TrackCriticizePattern)
            scored = evaluator.calc_score(tracks, track)
        else:
            scored = cls.get_scored_tracks(parameters, track, tracks)

        scored = scored[:RecommendApi.TRACK_COUNT_BASE]

        return scored