ADD: Handle Modified NoteSheeds
This commit is contained in:
parent
d221502bef
commit
007f6a8501
@ -60,4 +60,13 @@ public interface SongDao {
|
||||
|
||||
@Query("SELECT localID FROM Song WHERE serverID IN (:serverIDs)")
|
||||
List<Integer> getLocalSongIDsByServerIDs(List<String> serverIDs);
|
||||
|
||||
@Query("SELECT * FROM NoteSheet WHERE serverFileName IN (:serverFileNames)")
|
||||
List<NoteSheet> getNoteSheetsByServerFileNames(List<String> serverFileNames);
|
||||
|
||||
@Query("SELECT * FROM NoteSheet WHERE syncStatus = :status")
|
||||
List<NoteSheet> getNoteSheetsBySyncStatus(SyncStatus status);
|
||||
|
||||
@Query("SELECT * FROM NoteSheet WHERE songID IN (:localSongIDs)")
|
||||
List<NoteSheet> getNoteSheetFilesBySongIDs(List<Integer> localSongIDs);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.stormtales.notevault.data.entities;
|
||||
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.PrimaryKey;
|
||||
import com.stormtales.notevault.data.sync.SyncStatus;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@ -14,9 +15,12 @@ public class NoteSheet {
|
||||
private String serverFileName;
|
||||
private String hash;
|
||||
|
||||
private SyncStatus syncStatus;
|
||||
|
||||
public NoteSheet(String localFileName, String hash) {
|
||||
this.localFileName = localFileName;
|
||||
this.hash = hash;
|
||||
this.syncStatus = SyncStatus.CREATED;
|
||||
}
|
||||
|
||||
public int getLocalID() {
|
||||
@ -70,4 +74,12 @@ public class NoteSheet {
|
||||
public void setSongID(int songID) {
|
||||
this.songID = songID;
|
||||
}
|
||||
|
||||
public SyncStatus getSyncStatus() {
|
||||
return syncStatus;
|
||||
}
|
||||
|
||||
public void setSyncStatus(SyncStatus syncStatus) {
|
||||
this.syncStatus = syncStatus;
|
||||
}
|
||||
}
|
||||
|
@ -3,20 +3,20 @@ package com.stormtales.notevault.data.repositories;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import androidx.recyclerview.widget.AsyncListUtil;
|
||||
import com.stormtales.notevault.data.MusicDatabase;
|
||||
import com.stormtales.notevault.data.dao.SongDao;
|
||||
import com.stormtales.notevault.data.entities.NoteSheet;
|
||||
import com.stormtales.notevault.data.entities.Song;
|
||||
import com.stormtales.notevault.data.sync.SyncStatus;
|
||||
import com.stormtales.notevault.network.sync.models.BatchCreateResponse;
|
||||
import com.stormtales.notevault.network.sync.models.BatchModifyResponse;
|
||||
import com.stormtales.notevault.network.sync.models.CreateResponse;
|
||||
import com.stormtales.notevault.network.sync.models.UploadResponse;
|
||||
import com.stormtales.notevault.network.sync.models.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.stream.Collectors;
|
||||
@ -36,11 +36,16 @@ public class SongSyncRepository {
|
||||
});
|
||||
}
|
||||
|
||||
public void loadModifiedSongs(LoadDataCallback<List<Song>> callback) {
|
||||
public void loadModifiedSongs(LoadDataCallback<Map<Song, List<NoteSheet>>> callback) {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
Map<Song, List<NoteSheet>> result = new HashMap<>();
|
||||
List<Song> modifiedSongs = songDao.getSongsBySyncStatus(SyncStatus.MODIFIED);
|
||||
for(Song song : modifiedSongs) {
|
||||
List<NoteSheet> noteSheets = songDao.getNoteSheetsBySong(song.getLocalID());
|
||||
result.put(song, noteSheets);
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
mainHandler.post(()-> callback.onResult(modifiedSongs));
|
||||
mainHandler.post(()-> callback.onResult(result));
|
||||
});
|
||||
}
|
||||
|
||||
@ -78,13 +83,27 @@ public class SongSyncRepository {
|
||||
}
|
||||
}
|
||||
|
||||
public void markModifiedSongsAsSynced(BatchModifyResponse response) {
|
||||
public void markModifiedSongsAsSynced(SongModifyBatchResponse modifyBatchResponse) {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
List<Song> requestedSongs = songDao.getSongsByServerIDs(response.getModifiedServerObjects());
|
||||
List<String> serverIDs = modifyBatchResponse.getModifiedServerObjects().stream().map(SongModifyResponse::getServerID).collect(Collectors.toList());
|
||||
List<Song> requestedSongs = songDao.getSongsByServerIDs(serverIDs);
|
||||
for(Song song : requestedSongs) {
|
||||
song.setSyncStatus(SyncStatus.SYNCED);
|
||||
song.setSyncTime(LocalDateTime.now());
|
||||
|
||||
|
||||
for(SongModifyResponse modifyResponse : modifyBatchResponse.getModifiedServerObjects()) {
|
||||
if(modifyResponse.getServerID().equals(song.getServerID())) {
|
||||
List<NoteSheet> outdatedNoteSheets = songDao.getNoteSheetsByServerFileNames(modifyResponse.getOutdated_note_sheets());
|
||||
for(NoteSheet noteSheet : outdatedNoteSheets) {
|
||||
noteSheet.setSyncStatus(SyncStatus.MODIFIED);
|
||||
}
|
||||
songDao.updateNoteSheets(outdatedNoteSheets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
songDao.updateSongs(requestedSongs);
|
||||
});
|
||||
}
|
||||
@ -96,9 +115,9 @@ public class SongSyncRepository {
|
||||
});
|
||||
}
|
||||
|
||||
public void getNoteSheetFilesBySongIDs(List<Integer> songIDs, LoadDataCallback<List<NoteSheet>> callback) {
|
||||
public void getNoteSheetFilesBySongIDs(LoadDataCallback<List<NoteSheet>> callback) {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
List<NoteSheet> noteSheets = songDao.getNoteSheetsBySongIDs(songIDs);
|
||||
List<NoteSheet> noteSheets = songDao.getNoteSheetsBySyncStatus(SyncStatus.CREATED);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
mainHandler.post(()-> callback.onResult(noteSheets));
|
||||
});
|
||||
@ -114,6 +133,7 @@ public class SongSyncRepository {
|
||||
for(NoteSheet noteSheet : uploadedNoteSheets) {
|
||||
if(new File(noteSheet.getLocalFileName()).getName().equals(uploadResponse.getLocalFile())) {
|
||||
noteSheet.setServerFileName(uploadResponse.getServerFile());
|
||||
noteSheet.setSyncStatus(SyncStatus.SYNCED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -122,6 +142,27 @@ public class SongSyncRepository {
|
||||
});
|
||||
}
|
||||
|
||||
public void loadModifiedNoteSheets(LoadDataCallback<List<NoteSheet>> callback) {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
List<NoteSheet> noteSheets = songDao.getNoteSheetsBySyncStatus(SyncStatus.MODIFIED);
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
mainHandler.post(()-> callback.onResult(noteSheets));
|
||||
});
|
||||
}
|
||||
|
||||
public void markModifiedNoteSheetsAsSynced(List<UploadResponse> uploadResponses) {
|
||||
Executors.newSingleThreadExecutor().execute(() -> {
|
||||
List<String> serverFileNames = uploadResponses.stream().map(UploadResponse::getServerFile).collect(Collectors.toList());
|
||||
|
||||
|
||||
List<NoteSheet> noteSheets = songDao.getNoteSheetsByServerFileNames(serverFileNames);
|
||||
for(NoteSheet noteSheet : noteSheets) {
|
||||
noteSheet.setSyncStatus(SyncStatus.SYNCED);
|
||||
}
|
||||
songDao.updateNoteSheets(noteSheets);
|
||||
});
|
||||
}
|
||||
|
||||
public interface LoadDataCallback<T> {
|
||||
void onResult(T result);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public interface SongSyncAPI {
|
||||
Call<BatchCreateResponse> syncCreatedSongs(@Body SongCreateBatchRequest songCreateBatchRequest);
|
||||
|
||||
@POST("/sync/songs/modify")
|
||||
Call<BatchModifyResponse> syncModifiedSongs(@Body SongModifyBatchRequest songModifyBatchRequest);
|
||||
Call<SongModifyBatchResponse> syncModifiedSongs(@Body SongModifyBatchRequest songModifyBatchRequest);
|
||||
|
||||
@POST("/sync/songs/delete")
|
||||
Call<BatchModifyResponse> syncDeletedSongs(@Body SongBatchDeleteRequest songBatchDeleteRequest);
|
||||
@ -25,4 +25,8 @@ public interface SongSyncAPI {
|
||||
@Multipart
|
||||
@POST("/sync/songs/note_sheet/upload")
|
||||
Call<UploadResponse> uploadNoteSheet(@Part("serverID")RequestBody serverID, @Part("fileName") RequestBody fileName, @Part MultipartBody.Part image);
|
||||
|
||||
@Multipart
|
||||
@POST("/sync/songs/note_sheet/update")
|
||||
Call<UploadResponse> updateNoteSheet(@Part("server_filename") RequestBody server_filename, @Part MultipartBody.Part image);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import com.stormtales.notevault.data.repositories.SongRepository;
|
||||
import com.stormtales.notevault.data.repositories.SongSyncRepository;
|
||||
import com.stormtales.notevault.network.sync.models.BatchCreateResponse;
|
||||
import com.stormtales.notevault.network.sync.models.BatchModifyResponse;
|
||||
import com.stormtales.notevault.network.sync.models.SongModifyBatchResponse;
|
||||
import com.stormtales.notevault.network.sync.models.UploadResponse;
|
||||
import com.stormtales.notevault.ui.gallery.GalleryViewModel;
|
||||
|
||||
@ -33,23 +34,39 @@ public class SongSyncModule {
|
||||
if(response.getCreateResponses().isEmpty()) {
|
||||
syncViewModel.finishCreateSongSyncing();
|
||||
} else {
|
||||
List<Integer> songIDs = result.stream().map(Song::getLocalID).collect(Collectors.toList());
|
||||
songSyncRepository.getNoteSheetFilesBySongIDs(songIDs, noteSheets -> {
|
||||
songSyncService.uploadNoteSheetsOfCreatedSongs(noteSheets, response, uploadResponses -> {
|
||||
songSyncRepository.markCreatedNoteSheetsAsSynced(uploadResponses);
|
||||
syncViewModel.finishCreateSongSyncing();
|
||||
});
|
||||
});
|
||||
uploadCreatedNoteSheets(result, response);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void uploadCreatedNoteSheets(List<Song> result, BatchCreateResponse response) {
|
||||
List<Integer> songIDs = result.stream().map(Song::getLocalID).collect(Collectors.toList());
|
||||
songSyncRepository.getNoteSheetFilesBySongIDs(noteSheets -> {
|
||||
songSyncService.uploadNoteSheetsOfCreatedSongs(noteSheets, response, uploadResponses -> {
|
||||
songSyncRepository.markCreatedNoteSheetsAsSynced(uploadResponses);
|
||||
syncViewModel.finishCreateSongSyncing();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void syncModifiedSongs() {
|
||||
songSyncRepository.loadModifiedSongs(result -> {
|
||||
songSyncService.syncModifiedSongs(result, response -> {
|
||||
songSyncService.syncModifiedSongs(result, (FinishSongSyncingCallback<SongModifyBatchResponse>) response -> {
|
||||
songSyncRepository.markModifiedSongsAsSynced(response);
|
||||
syncViewModel.finishModifiedSongSyncinc();
|
||||
uploadModifiedNoteSheets();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void uploadModifiedNoteSheets() {
|
||||
songSyncRepository.loadModifiedNoteSheets(modifiedNoteSheets -> {
|
||||
songSyncService.uploadModifiedNoteSheets(modifiedNoteSheets, new SongSyncService.UploadNoteSheetCallback() {
|
||||
@Override
|
||||
public void finishUploadNoteSheets(List<UploadResponse> uploadResponses) {
|
||||
songSyncRepository.markModifiedNoteSheetsAsSynced(uploadResponses);
|
||||
syncViewModel.finishModifiedSongSyncinc();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -67,7 +84,7 @@ public class SongSyncModule {
|
||||
void finishSongSyncing(BatchCreateResponse response);
|
||||
}
|
||||
|
||||
public interface FinishSongSyncingCallback {
|
||||
void finishSongSyncing(BatchModifyResponse response);
|
||||
public interface FinishSongSyncingCallback<T> {
|
||||
void finishSongSyncing(T response);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.stormtales.notevault.network.sync;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import com.stormtales.notevault.data.entities.NoteSheet;
|
||||
import com.stormtales.notevault.data.entities.Song;
|
||||
import com.stormtales.notevault.network.NetworkModule;
|
||||
@ -17,6 +18,7 @@ import retrofit2.Response;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SongSyncService {
|
||||
private final SongSyncAPI songSyncAPI;
|
||||
@ -79,20 +81,20 @@ public class SongSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
public void syncModifiedSongs(List<Song> songs, SongSyncModule.FinishSongSyncingCallback callback) {
|
||||
public void syncModifiedSongs(Map<Song, List<NoteSheet>> songs, SongSyncModule.FinishSongSyncingCallback<SongModifyBatchResponse> callback) {
|
||||
List<SongModifyRequest> modifyRequests = new ArrayList<>();
|
||||
for(Song song : songs) {
|
||||
modifyRequests.add(new SongModifyRequest(song));
|
||||
for(Map.Entry<Song, List<NoteSheet>> entry: songs.entrySet()) {
|
||||
modifyRequests.add(new SongModifyRequest(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
SongModifyBatchRequest songModifyBatchRequest = new SongModifyBatchRequest(modifyRequests);
|
||||
songSyncAPI.syncModifiedSongs(songModifyBatchRequest).enqueue(new Callback<BatchModifyResponse>() {
|
||||
songSyncAPI.syncModifiedSongs(songModifyBatchRequest).enqueue(new Callback<SongModifyBatchResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<BatchModifyResponse> call, Response<BatchModifyResponse> response) {
|
||||
public void onResponse(Call<SongModifyBatchResponse> call, Response<SongModifyBatchResponse> response) {
|
||||
callback.finishSongSyncing(response.body());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<BatchModifyResponse> call, Throwable throwable) {
|
||||
public void onFailure(Call<SongModifyBatchResponse> call, Throwable throwable) {
|
||||
|
||||
}
|
||||
});
|
||||
@ -125,6 +127,34 @@ public class SongSyncService {
|
||||
});
|
||||
}
|
||||
|
||||
public void uploadModifiedNoteSheets(List<NoteSheet> modifiedNoteSheets, UploadNoteSheetCallback callback) {
|
||||
List<UploadResponse> uploadResponses = new ArrayList<>();
|
||||
for(NoteSheet noteSheet : modifiedNoteSheets) {
|
||||
RequestBody server_filename = RequestBody.create(MediaType.parse("text/plain"), noteSheet.getServerFileName());
|
||||
|
||||
RequestBody requestFile = RequestBody.create(MediaType.parse("image/**"), new File(noteSheet.getLocalFileName()));
|
||||
MultipartBody.Part image = MultipartBody.Part.createFormData("image", noteSheet.getLocalFileName(), requestFile);
|
||||
|
||||
songSyncAPI.updateNoteSheet(server_filename, image).enqueue(new Callback<UploadResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<UploadResponse> call, Response<UploadResponse> response) {
|
||||
if(response.isSuccessful() && response.body() != null) {
|
||||
uploadResponses.add(response.body());
|
||||
if(uploadResponses.size() == modifiedNoteSheets.size()) {
|
||||
callback.finishUploadNoteSheets(uploadResponses);
|
||||
}
|
||||
} else {
|
||||
Log.d("SongSyncService", "Something went wrong");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<UploadResponse> call, Throwable throwable) {
|
||||
Log.e("SongSyncService", "Upload failed: " + throwable.getMessage(), throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface SyncDeletedSongsCallback {
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.stormtales.notevault.network.sync.models;
|
||||
|
||||
public class NoteSheetModifyRequest {
|
||||
private String serverFileName;
|
||||
private String clientHash;
|
||||
|
||||
public NoteSheetModifyRequest(String serverFileName, String clientHash) {
|
||||
this.serverFileName = serverFileName;
|
||||
this.clientHash = clientHash;
|
||||
}
|
||||
|
||||
public String getServerFileName() {
|
||||
return serverFileName;
|
||||
}
|
||||
|
||||
public void setServerFileName(String serverFileName) {
|
||||
this.serverFileName = serverFileName;
|
||||
}
|
||||
|
||||
public String getClientHash() {
|
||||
return clientHash;
|
||||
}
|
||||
|
||||
public void setClientHash(String clientHash) {
|
||||
this.clientHash = clientHash;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.stormtales.notevault.network.sync.models;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SongModifyBatchResponse {
|
||||
|
||||
private List<SongModifyResponse> modifiedServerObjects;
|
||||
|
||||
public List<SongModifyResponse> getModifiedServerObjects() {
|
||||
return modifiedServerObjects;
|
||||
}
|
||||
|
||||
public void setModifiedServerObjects(List<SongModifyResponse> modifiedServerObjects) {
|
||||
this.modifiedServerObjects = modifiedServerObjects;
|
||||
}
|
||||
}
|
@ -1,7 +1,11 @@
|
||||
package com.stormtales.notevault.network.sync.models;
|
||||
|
||||
import com.stormtales.notevault.data.entities.NoteSheet;
|
||||
import com.stormtales.notevault.data.entities.Song;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SongModifyRequest {
|
||||
|
||||
private String serverID;
|
||||
@ -9,6 +13,7 @@ public class SongModifyRequest {
|
||||
private String composer;
|
||||
private String genre;
|
||||
private int year;
|
||||
private List<NoteSheetModifyRequest> noteSheets;
|
||||
|
||||
public SongModifyRequest(String serverID, String title, String composer, String genre, int year) {
|
||||
this.serverID = serverID;
|
||||
@ -18,12 +23,13 @@ public class SongModifyRequest {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public SongModifyRequest(Song song) {
|
||||
public SongModifyRequest(Song song, List<NoteSheet> noteSheets) {
|
||||
this.serverID = song.getServerID();
|
||||
this.title = song.getTitle();
|
||||
this.composer = song.getComposer();
|
||||
this.genre = song.getGenre();
|
||||
this.year = song.getYear();
|
||||
this.noteSheets = noteSheets.stream().map(noteSheet -> new NoteSheetModifyRequest(noteSheet.getServerFileName(), noteSheet.getHash())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public String getServerID() {
|
||||
@ -65,4 +71,12 @@ public class SongModifyRequest {
|
||||
public void setYear(int year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public List<NoteSheetModifyRequest> getNoteSheets() {
|
||||
return noteSheets;
|
||||
}
|
||||
|
||||
public void setNoteSheets(List<NoteSheetModifyRequest> noteSheets) {
|
||||
this.noteSheets = noteSheets;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
package com.stormtales.notevault.network.sync.models;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SongModifyResponse {
|
||||
|
||||
private String serverID;
|
||||
private List<String> outdated_note_sheets;
|
||||
|
||||
public List<String> getOutdated_note_sheets() {
|
||||
return outdated_note_sheets;
|
||||
}
|
||||
|
||||
public void setOutdated_note_sheets(List<String> outdated_note_sheets) {
|
||||
this.outdated_note_sheets = outdated_note_sheets;
|
||||
}
|
||||
|
||||
public String getServerID() {
|
||||
return serverID;
|
||||
}
|
||||
|
||||
public void setServerID(String serverID) {
|
||||
this.serverID = serverID;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user