From 92ef22596bd4070bf0bc513e0512314d2479bf7c Mon Sep 17 00:00:00 2001 From: geoffrey45 Date: Sun, 26 Jun 2022 18:46:17 +0300 Subject: [PATCH] fix removing duplicate tracks - add uniq_hash prop to Track class --- server/app/api/album.py | 1 + server/app/api/artist.py | 66 ++++++++++++++++++------------------- server/app/api/search.py | 1 + server/app/helpers.py | 25 +++++--------- server/app/lib/trackslib.py | 50 +--------------------------- server/app/models.py | 12 +++++++ 6 files changed, 57 insertions(+), 98 deletions(-) diff --git a/server/app/api/album.py b/server/app/api/album.py index e37c185b..eff42f82 100644 --- a/server/app/api/album.py +++ b/server/app/api/album.py @@ -45,6 +45,7 @@ def get_album(): tracks = instances.tracks_instance.find_tracks_by_hash(albumhash) tracks = [models.Track(t) for t in tracks] + tracks = helpers.RemoveDuplicates(tracks)() album = instances.album_instance.find_album_by_hash(albumhash) diff --git a/server/app/api/artist.py b/server/app/api/artist.py index 0958197a..e82d02c3 100644 --- a/server/app/api/artist.py +++ b/server/app/api/artist.py @@ -11,48 +11,48 @@ from flask import Blueprint artist_bp = Blueprint("artist", __name__, url_prefix="/") -@artist_bp.route("/artist/") -@cache.cached() -def get_artist_data(artist: str): - """Returns the artist's data, tracks and albums""" - artist = urllib.parse.unquote(artist) - artist_obj = instances.artist_instance.get_artists_by_name(artist) +# @artist_bp.route("/artist/") +# @cache.cached() +# def get_artist_data(artist: str): +# """Returns the artist's data, tracks and albums""" +# artist = urllib.parse.unquote(artist) +# artist_obj = instances.artist_instance.get_artists_by_name(artist) - def get_artist_tracks(): - songs = instances.tracks_instance.find_songs_by_artist(artist) +# def get_artist_tracks(): +# songs = instances.tracks_instance.find_songs_by_artist(artist) - return songs +# return songs - artist_songs = get_artist_tracks() - songs = helpers.remove_duplicates(artist_songs) +# artist_songs = get_artist_tracks() +# songs = helpers.remove_duplicates(artist_songs) - def get_artist_albums(): - artist_albums = [] - albums_with_count = [] +# def get_artist_albums(): +# artist_albums = [] +# albums_with_count = [] - albums = instances.tracks_instance.find_songs_by_albumartist(artist) +# albums = instances.tracks_instance.find_songs_by_albumartist(artist) - for song in albums: - if song["album"] not in artist_albums: - artist_albums.append(song["album"]) +# for song in albums: +# if song["album"] not in artist_albums: +# artist_albums.append(song["album"]) - for album in artist_albums: - count = 0 - length = 0 +# for album in artist_albums: +# count = 0 +# length = 0 - for song in artist_songs: - if song["album"] == album: - count = count + 1 - length = length + song["length"] +# for song in artist_songs: +# if song["album"] == album: +# count = count + 1 +# length = length + song["length"] - album_ = {"title": album, "count": count, "length": length} +# album_ = {"title": album, "count": count, "length": length} - albums_with_count.append(album_) +# albums_with_count.append(album_) - return albums_with_count +# return albums_with_count - return { - "artist": artist_obj, - "songs": songs, - "albums": get_artist_albums() - } +# return { +# "artist": artist_obj, +# "songs": songs, +# "albums": get_artist_albums() +# } diff --git a/server/app/api/search.py b/server/app/api/search.py index 15ab35ca..cb90f543 100644 --- a/server/app/api/search.py +++ b/server/app/api/search.py @@ -48,6 +48,7 @@ class DoSearch: """ self.tracks = helpers.Get.get_all_tracks() tracks = searchlib.SearchTracks(self.tracks, self.query)() + tracks = helpers.RemoveDuplicates(tracks)() SearchResults.tracks = tracks return tracks diff --git a/server/app/helpers.py b/server/app/helpers.py index 6cdd9dec..d0ebfdc6 100644 --- a/server/app/helpers.py +++ b/server/app/helpers.py @@ -1,7 +1,9 @@ """ This module contains mini functions for the server. """ +from dataclasses import dataclass import os +from pprint import pprint import threading from datetime import datetime from typing import Dict, Set @@ -51,26 +53,17 @@ def run_fast_scandir(__dir: str, full=False) -> Dict[List[str], List[str]]: return subfolders, files -def remove_duplicates(tracklist: List[models.Track]) -> List[models.Track]: - """ - Removes duplicates from a list. Returns a list without duplicates. - """ - song_num = 0 - while song_num < len(tracklist) - 1: - for index, song in enumerate(tracklist): - if ( - tracklist[song_num].title == song.title - and tracklist[song_num].album == song.album - and tracklist[song_num].artists == song.artists - and index != song_num - ): - tracklist.remove(song) +class RemoveDuplicates: + def __init__(self, tracklist: List[models.Track]) -> None: + self.tracklist = tracklist - song_num += 1 + def __call__(self) -> List[models.Track]: + uniq_hashes = set(t.uniq_hash for t in self.tracklist) + tracks = UseBisection(self.tracklist, "uniq_hash", uniq_hashes)() - return tracklist + return tracks def is_valid_file(filename: str) -> bool: diff --git a/server/app/lib/trackslib.py b/server/app/lib/trackslib.py index 34d037e2..f48847f2 100644 --- a/server/app/lib/trackslib.py +++ b/server/app/lib/trackslib.py @@ -2,11 +2,8 @@ This library contains all the functions related to tracks. """ import os -from pprint import pprint -from typing import List -from app import api, instances, models -from app.helpers import remove_duplicates +from app import instances from tqdm import tqdm @@ -23,51 +20,6 @@ def validate_tracks() -> None: instances.tracks_instance.remove_song_by_id(track["_id"]["$oid"]) -def get_album_tracks(albumname, artist): - """Returns api tracks matching an album""" - _tracks: List[models.Track] = [] - - for track in api.TRACKS: - if track.album == albumname and track.albumartist == artist: - _tracks.append(track) - - return remove_duplicates(_tracks) - - -def get_track_by_id(trackid: str) -> models.Track: - """Returns api track matching an id""" - for track in api.TRACKS: - try: - if track.trackid == trackid: - return track - except AttributeError: - print("AttributeError") - - -def find_track(tracks: list, hash: str) -> int | None: - """ - Finds an album by album title and artist. - """ - - left = 0 - right = len(tracks) - 1 - iter = 0 - - while left <= right: - iter += 1 - mid = (left + right) // 2 - - if tracks[mid]["albumhash"] == hash: - return mid - - if tracks[mid]["albumhash"] < hash: - left = mid + 1 - else: - right = mid - 1 - - return None - - def get_p_track(ptrack): return instances.tracks_instance.find_track_by_title_artists_album( ptrack["title"], ptrack["artists"], ptrack["album"] diff --git a/server/app/models.py b/server/app/models.py index 1c461294..915e225c 100644 --- a/server/app/models.py +++ b/server/app/models.py @@ -29,6 +29,7 @@ class Track: albumhash: str date: str image: str + uniq_hash: str def __init__(self, tags): self.trackid = tags["_id"]["$oid"] @@ -47,6 +48,17 @@ class Track: self.image = tags["albumhash"] + ".webp" self.tracknumber = int(tags["tracknumber"]) + self.uniq_hash = self.create_unique_hash( + "".join(self.artists), self.album, self.title + ) + + @staticmethod + def create_unique_hash(*args): + ill_chars = '/\\:*?"<>|#&' + + string = "".join(str(a) for a in args).replace(" ", "") + return "".join(string).strip(ill_chars).lower() + @dataclass(slots=True) class Artist: