Merge branch 'development' into skip-duplicates

This commit is contained in:
eddyizm 2025-10-06 22:22:52 -07:00 committed by GitHub
commit 717f95a04a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
87 changed files with 6098 additions and 428 deletions

View file

@ -2,10 +2,12 @@ package com.cappielloantonio.tempo.repository;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
import android.util.Log;
import com.cappielloantonio.tempo.App;
import com.cappielloantonio.tempo.subsonic.base.ApiResponse;
import com.cappielloantonio.tempo.subsonic.models.ArtistID3;
import com.cappielloantonio.tempo.subsonic.models.AlbumID3;
import com.cappielloantonio.tempo.subsonic.models.ArtistInfo2;
import com.cappielloantonio.tempo.subsonic.models.Child;
import com.cappielloantonio.tempo.subsonic.models.IndexID3;
@ -13,12 +15,92 @@ import com.cappielloantonio.tempo.subsonic.models.IndexID3;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class ArtistRepository {
private final AlbumRepository albumRepository;
public ArtistRepository() {
this.albumRepository = new AlbumRepository();
}
public void getArtistAllSongs(String artistId, ArtistSongsCallback callback) {
Log.d("ArtistSync", "Getting albums for artist: " + artistId);
// Get the artist info first, which contains the albums
App.getSubsonicClientInstance(false)
.getBrowsingClient()
.getArtist(artistId)
.enqueue(new Callback<ApiResponse>() {
@Override
public void onResponse(@NonNull Call<ApiResponse> call, @NonNull Response<ApiResponse> response) {
if (response.isSuccessful() && response.body() != null &&
response.body().getSubsonicResponse().getArtist() != null &&
response.body().getSubsonicResponse().getArtist().getAlbums() != null) {
List<AlbumID3> albums = response.body().getSubsonicResponse().getArtist().getAlbums();
Log.d("ArtistSync", "Got albums directly: " + albums.size());
if (!albums.isEmpty()) {
fetchAllAlbumSongsWithCallback(albums, callback);
} else {
Log.d("ArtistSync", "No albums found in artist response");
callback.onSongsCollected(new ArrayList<>());
}
} else {
Log.d("ArtistSync", "Failed to get artist info");
callback.onSongsCollected(new ArrayList<>());
}
}
@Override
public void onFailure(@NonNull Call<ApiResponse> call, @NonNull Throwable t) {
Log.d("ArtistSync", "Error getting artist info: " + t.getMessage());
callback.onSongsCollected(new ArrayList<>());
}
});
}
private void fetchAllAlbumSongsWithCallback(List<AlbumID3> albums, ArtistSongsCallback callback) {
if (albums == null || albums.isEmpty()) {
Log.d("ArtistSync", "No albums to process");
callback.onSongsCollected(new ArrayList<>());
return;
}
List<Child> allSongs = new ArrayList<>();
AtomicInteger remainingAlbums = new AtomicInteger(albums.size());
Log.d("ArtistSync", "Processing " + albums.size() + " albums");
for (AlbumID3 album : albums) {
Log.d("ArtistSync", "Getting tracks for album: " + album.getName());
MutableLiveData<List<Child>> albumTracks = albumRepository.getAlbumTracks(album.getId());
albumTracks.observeForever(songs -> {
Log.d("ArtistSync", "Got " + (songs != null ? songs.size() : 0) + " songs from album");
if (songs != null) {
allSongs.addAll(songs);
}
albumTracks.removeObservers(null);
int remaining = remainingAlbums.decrementAndGet();
Log.d("ArtistSync", "Remaining albums: " + remaining);
if (remaining == 0) {
Log.d("ArtistSync", "All albums processed. Total songs: " + allSongs.size());
callback.onSongsCollected(allSongs);
}
});
}
}
public interface ArtistSongsCallback {
void onSongsCollected(List<Child> songs);
}
public MutableLiveData<List<ArtistID3>> getStarredArtists(boolean random, int size) {
MutableLiveData<List<ArtistID3>> starredArtists = new MutableLiveData<>(new ArrayList<>());
@ -89,7 +171,7 @@ public class ArtistRepository {
}
/*
* Metodo che mi restituisce le informazioni essenzionali dell'artista (cover, numero di album...)
* Method that returns essential artist information (cover, album number, etc.)
*/
public void getArtistInfo(List<ArtistID3> artists, MutableLiveData<List<ArtistID3>> list) {
List<ArtistID3> liveArtists = list.getValue();

View file

@ -18,6 +18,20 @@ public class DownloadRepository {
return downloadDao.getAll();
}
public List<Download> getAllDownloads() {
GetAllDownloadsThreadSafe getDownloads = new GetAllDownloadsThreadSafe(downloadDao);
Thread thread = new Thread(getDownloads);
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return getDownloads.getDownloads();
}
public Download getDownload(String id) {
Download download = null;
@ -35,6 +49,24 @@ public class DownloadRepository {
return download;
}
private static class GetAllDownloadsThreadSafe implements Runnable {
private final DownloadDao downloadDao;
private List<Download> downloads;
public GetAllDownloadsThreadSafe(DownloadDao downloadDao) {
this.downloadDao = downloadDao;
}
@Override
public void run() {
downloads = downloadDao.getAllSync();
}
public List<Download> getDownloads() {
return downloads;
}
}
private static class GetDownloadThreadSafe implements Runnable {
private final DownloadDao downloadDao;
private final String id;
@ -143,6 +175,12 @@ public class DownloadRepository {
thread.start();
}
public void delete(List<String> ids) {
DeleteMultipleThreadSafe delete = new DeleteMultipleThreadSafe(downloadDao, ids);
Thread thread = new Thread(delete);
thread.start();
}
private static class DeleteThreadSafe implements Runnable {
private final DownloadDao downloadDao;
private final String id;
@ -157,4 +195,19 @@ public class DownloadRepository {
downloadDao.delete(id);
}
}
private static class DeleteMultipleThreadSafe implements Runnable {
private final DownloadDao downloadDao;
private final List<String> ids;
public DeleteMultipleThreadSafe(DownloadDao downloadDao, List<String> ids) {
this.downloadDao = downloadDao;
this.ids = ids;
}
@Override
public void run() {
downloadDao.deleteByIds(ids);
}
}
}

View file

@ -0,0 +1,92 @@
package com.cappielloantonio.tempo.repository;
import androidx.lifecycle.LiveData;
import com.cappielloantonio.tempo.database.AppDatabase;
import com.cappielloantonio.tempo.database.dao.LyricsDao;
import com.cappielloantonio.tempo.model.LyricsCache;
public class LyricsRepository {
private final LyricsDao lyricsDao = AppDatabase.getInstance().lyricsDao();
public LyricsCache getLyrics(String songId) {
GetLyricsThreadSafe getLyricsThreadSafe = new GetLyricsThreadSafe(lyricsDao, songId);
Thread thread = new Thread(getLyricsThreadSafe);
thread.start();
try {
thread.join();
return getLyricsThreadSafe.getLyrics();
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
public LiveData<LyricsCache> observeLyrics(String songId) {
return lyricsDao.observeOne(songId);
}
public void insert(LyricsCache lyricsCache) {
InsertThreadSafe insert = new InsertThreadSafe(lyricsDao, lyricsCache);
Thread thread = new Thread(insert);
thread.start();
}
public void delete(String songId) {
DeleteThreadSafe delete = new DeleteThreadSafe(lyricsDao, songId);
Thread thread = new Thread(delete);
thread.start();
}
private static class GetLyricsThreadSafe implements Runnable {
private final LyricsDao lyricsDao;
private final String songId;
private LyricsCache lyricsCache;
public GetLyricsThreadSafe(LyricsDao lyricsDao, String songId) {
this.lyricsDao = lyricsDao;
this.songId = songId;
}
@Override
public void run() {
lyricsCache = lyricsDao.getOne(songId);
}
public LyricsCache getLyrics() {
return lyricsCache;
}
}
private static class InsertThreadSafe implements Runnable {
private final LyricsDao lyricsDao;
private final LyricsCache lyricsCache;
public InsertThreadSafe(LyricsDao lyricsDao, LyricsCache lyricsCache) {
this.lyricsDao = lyricsDao;
this.lyricsCache = lyricsCache;
}
@Override
public void run() {
lyricsDao.insert(lyricsCache);
}
}
private static class DeleteThreadSafe implements Runnable {
private final LyricsDao lyricsDao;
private final String songId;
public DeleteThreadSafe(LyricsDao lyricsDao, String songId) {
this.lyricsDao = lyricsDao;
this.songId = songId;
}
@Override
public void run() {
lyricsDao.delete(songId);
}
}
}