def request_to_parameters(self, criticize_type, track, request_parameters):
        if criticize_type != TrackCriticizeType.Parameter and not track:
            raise Exception("Target track is None")

        parameters = []
        if criticize_type == TrackCriticizeType.Parameter:
            if "bpm" in request_parameters:
                parameters.append(Parameter("bpm", request_parameters["bpm"]))

        elif criticize_type == TrackCriticizeType.Pattern:
            criticize = CriticizePattern(pattern=request_parameters["pattern"])
            direction = criticize.get_direction()
            parameters.append(Parameter("pattern", criticize.pattern))
            for c in criticize.get_targets():
                parameters.append(Parameter(c.name, vector_utils.to_value(getattr(track, c.name)), direction))

        elif criticize_type == TrackCriticizeType.Like:
            for c in self.__get_criticizables():
                parameters.append(Parameter(c, vector_utils.to_value(getattr(track, c))))

        if "q" in request_parameters and request_parameters["q"]:
            parameters.append(Parameter("q", request_parameters["q"]))

        if Parameter.first_or_default("genre", parameters) and not Parameter.first_or_default("genre_score", parameters):
            genre = Parameter.first_or_default("genre", parameters)
            if Track.genre_to_score(genre):
                g_score = Track.genre_to_score(genre)
                parameters.append(Parameter("genre_score", g_score))

        return parameters
Beispiel #2
0
    def __get_track(cls, track_id, tracks):
        if not track_id:
            Exception("Track id is not defined")

        track = None
        track = next(iter(filter(lambda t: t.id == track_id, tracks)), None)
        if track is None:
            track = Track.find_by_id(track_id)

        return track
Beispiel #3
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
    def get_default_conditions(cls):
        default_condition = {}
        base_date = datetime.now() - timedelta(days=730)
        default_condition["created_at"] = {"from": base_date.strftime("%Y-%m-%d %H:%M:%S")}

        random_score = random.uniform(-1, 1)
        random_genres = Track.score_to_genres(random_score, 1)
        default_condition["genres"] = ",".join(random_genres)

        default_condition["filter"] = "streamable"

        return default_condition
    def parameters_to_conditions(self, parameters):
        default_condition = self.get_default_conditions()

        c_dict = {}
        is_condition_set = False
        for key in self.__get_conditionables():
            p = Parameter.first_or_default(key, parameters)
            if p is not None and p.value is not None:
                is_condition_set = True
                if key == "bpm":
                    value = int(p.value)
                    if p.direction == CriticizeDirection.Up:
                        c_dict[key] = {"from": self.adjust_parameter(key, value, True)}
                    elif p.direction == CriticizeDirection.Down:
                        c_dict[key] = {"to": self.adjust_parameter(key, value, False)}
                    else:
                        c_dict[key] = {"from": self.adjust_parameter(key, value, False),
                                       "to": self.adjust_parameter(key, value, True)}

                elif key == "genre_score":
                    if p.direction == CriticizeDirection.Around:
                        c_dict[key] = p.value
                    else:
                        c_dict[key] = self.adjust_parameter(key, p.value, p.direction == CriticizeDirection.Up)

                elif key == "created_at":
                    value = self.adjust_parameter(key, p.value, p.direction == CriticizeDirection.Up)
                    c_dict[key] = {"from": value.strftime("%Y-%m-%d %H:%M:%S")}

                else:
                    c_dict[key] = p.value

        if "genre_score" in c_dict:
            genre = Track.score_to_genre(c_dict["genre_score"])
            c_dict["genres"] = genre
            c_dict.pop("genre_score")
        elif "genre" in c_dict:
            c_dict["genres"] = c_dict["genre"]

        if "genre" in c_dict:
            c_dict.pop("genre")

        if is_condition_set:
            c_dict["filter"] = default_condition["filter"]
        else:
            c_dict = default_condition

        return c_dict
Beispiel #6
0
    def get_criticize_pattern(cls, request):
        if request.method == "POST":
            posted = json.loads(request.body.decode("utf-8"))
            track_id = posted["track_id"]

            tracks = cls.__get_session_tracks(request)
            track = cls.__get_track(track_id, tracks)

            evaluator = Track.make_evaluator()
            criticize_patterns = evaluator.make_pattern(tracks, track)

            questions = TrackCriticizePattern.patterns_to_questions(criticize_patterns, track, tracks)
            serialized_question = json.dumps(questions)
            return HttpResponse(serialized_question, content_type="application/json")
        else:
            raise Exception("You have to use POST method when access the get_criticize_pattern.")
Beispiel #7
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]))
Beispiel #8
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