Added ability to scan library in SettingsFragment

This commit is contained in:
CappielloAntonio 2021-08-11 10:58:40 +02:00
parent 0c30e95c31
commit c1d10e6ed0
11 changed files with 239 additions and 22 deletions

View file

@ -0,0 +1,8 @@
package com.cappielloantonio.play.interfaces;
public interface ScanCallback {
void onError(Exception exception);
void onSuccess(boolean isScanning, long count);
}

View file

@ -0,0 +1,60 @@
package com.cappielloantonio.play.repository;
import android.app.Application;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.interfaces.ScanCallback;
import com.cappielloantonio.play.interfaces.SystemCallback;
import com.cappielloantonio.play.subsonic.models.ResponseStatus;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import retrofit2.Call;
import retrofit2.Callback;
public class ScanRepository {
private static final String TAG = "SongRepository";
private Application application;
public ScanRepository(Application application) {
this.application = application;
}
public void startScan(ScanCallback callback) {
App.getSubsonicClientInstance(application, false)
.getMediaLibraryScanningClient()
.startScan()
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, retrofit2.Response<SubsonicResponse> response) {
if (response.body().getScanStatus() != null) {
callback.onSuccess(response.body().getScanStatus().isScanning(), response.body().getScanStatus().getCount());
}
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
callback.onError(new Exception(t.getMessage()));
}
});
}
public void getScanStatus(ScanCallback callback) {
App.getSubsonicClientInstance(application, false)
.getMediaLibraryScanningClient()
.startScan()
.enqueue(new Callback<SubsonicResponse>() {
@Override
public void onResponse(Call<SubsonicResponse> call, retrofit2.Response<SubsonicResponse> response) {
if (response.body().getScanStatus() != null) {
callback.onSuccess(response.body().getScanStatus().isScanning(), response.body().getScanStatus().getCount());
}
}
@Override
public void onFailure(Call<SubsonicResponse> call, Throwable t) {
callback.onError(new Exception(t.getMessage()));
}
});
}
}

View file

@ -20,7 +20,8 @@ public class SystemRepository {
}
public void checkUserCredential(SystemCallback callback) {
App.getSubsonicClientInstance(application, false).getSystemClient()
App.getSubsonicClientInstance(application, false)
.getSystemClient()
.ping()
.enqueue(new Callback<SubsonicResponse>() {
@Override

View file

@ -3,6 +3,7 @@ package com.cappielloantonio.play.subsonic;
import com.cappielloantonio.play.subsonic.api.albumsonglist.AlbumSongListClient;
import com.cappielloantonio.play.subsonic.api.browsing.BrowsingClient;
import com.cappielloantonio.play.subsonic.api.mediaannotation.MediaAnnotationClient;
import com.cappielloantonio.play.subsonic.api.medialibraryscanning.MediaLibraryScanningClient;
import com.cappielloantonio.play.subsonic.api.mediaretrieval.MediaRetrievalClient;
import com.cappielloantonio.play.subsonic.api.playlist.PlaylistClient;
import com.cappielloantonio.play.subsonic.api.searching.SearchingClient;
@ -25,6 +26,7 @@ public class Subsonic {
private SearchingClient searchingClient;
private AlbumSongListClient albumSongListClient;
private MediaAnnotationClient mediaAnnotationClient;
private MediaLibraryScanningClient mediaLibraryScanningClient;
public Subsonic(SubsonicPreferences preferences) {
this.preferences = preferences;
@ -83,6 +85,13 @@ public class Subsonic {
return mediaAnnotationClient;
}
public MediaLibraryScanningClient getMediaLibraryScanningClient() {
if (mediaLibraryScanningClient == null) {
mediaLibraryScanningClient = new MediaLibraryScanningClient(this);
}
return mediaLibraryScanningClient;
}
public String getUrl() {
String url = preferences.getServerUrl() + "/rest/";

View file

@ -0,0 +1,56 @@
package com.cappielloantonio.play.subsonic.api.medialibraryscanning;
import android.util.Log;
import com.cappielloantonio.play.subsonic.Subsonic;
import com.cappielloantonio.play.subsonic.api.system.SystemService;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import com.tickaroo.tikxml.retrofit.TikXmlConverterFactory;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Call;
import retrofit2.Retrofit;
public class MediaLibraryScanningClient {
private static final String TAG = "SystemClient";
private Subsonic subsonic;
private Retrofit retrofit;
private MediaLibraryScanningService mediaLibraryScanningService;
public MediaLibraryScanningClient(Subsonic subsonic) {
this.subsonic = subsonic;
this.retrofit = new Retrofit.Builder()
.baseUrl(subsonic.getUrl())
.addConverterFactory(TikXmlConverterFactory.create())
.client(getOkHttpClient())
.build();
this.mediaLibraryScanningService = retrofit.create(MediaLibraryScanningService.class);
}
public Call<SubsonicResponse> startScan() {
Log.d(TAG, "startScan()");
return mediaLibraryScanningService.startScan(subsonic.getParams());
}
public Call<SubsonicResponse> getScanStatus() {
Log.d(TAG, "getScanStatus()");
return mediaLibraryScanningService.getScanStatus(subsonic.getParams());
}
private OkHttpClient getOkHttpClient() {
return new OkHttpClient.Builder()
.addInterceptor(getHttpLoggingInterceptor())
.build();
}
private HttpLoggingInterceptor getHttpLoggingInterceptor() {
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return loggingInterceptor;
}
}

View file

@ -0,0 +1,17 @@
package com.cappielloantonio.play.subsonic.api.medialibraryscanning;
import com.cappielloantonio.play.subsonic.models.SubsonicResponse;
import java.util.Map;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.QueryMap;
public interface MediaLibraryScanningService {
@GET("startScan")
Call<SubsonicResponse> startScan(@QueryMap Map<String, String> params);
@GET("getScanStatus")
Call<SubsonicResponse> getScanStatus(@QueryMap Map<String, String> params);
}

View file

@ -1,39 +1,27 @@
package com.cappielloantonio.play.subsonic.models;
public class ScanStatus {
protected boolean scanning;
protected Long count;
import com.tickaroo.tikxml.annotation.Attribute;
import com.tickaroo.tikxml.annotation.Xml;
/**
* Gets the value of the scanning property.
*/
@Xml
public class ScanStatus {
@Attribute
protected boolean scanning;
@Attribute
protected Long count;
public boolean isScanning() {
return scanning;
}
/**
* Sets the value of the scanning property.
*/
public void setScanning(boolean value) {
this.scanning = value;
}
/**
* Gets the value of the count property.
*
* @return possible object is
* {@link Long }
*/
public Long getCount() {
return count;
}
/**
* Sets the value of the count property.
*
* @param value allowed object is
* {@link Long }
*/
public void setCount(Long value) {
this.count = value;
}

View file

@ -9,6 +9,7 @@ import com.tickaroo.tikxml.annotation.Xml;
public class SubsonicResponse {
@Element
private Error error;
@Element(name = "scanStatus")
private ScanStatus scanStatus;
@Element(name = "topSongs")
private TopSongs topSongs;

View file

@ -4,7 +4,9 @@ import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.lifecycle.ViewModelProvider;
import androidx.preference.ListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
@ -12,20 +14,25 @@ import androidx.preference.PreferenceFragmentCompat;
import com.cappielloantonio.play.App;
import com.cappielloantonio.play.R;
import com.cappielloantonio.play.helper.ThemeHelper;
import com.cappielloantonio.play.interfaces.ScanCallback;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.ui.activity.MainActivity;
import com.cappielloantonio.play.util.PreferenceUtil;
import com.cappielloantonio.play.viewmodel.LibraryViewModel;
import com.cappielloantonio.play.viewmodel.SettingViewModel;
public class SettingsFragment extends PreferenceFragmentCompat {
private static final String TAG = "SettingsFragment";
private MainActivity activity;
private SettingViewModel settingViewModel;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activity = (MainActivity) getActivity();
View view = super.onCreateView(inflater, container, savedInstanceState);
settingViewModel = new ViewModelProvider(requireActivity()).get(SettingViewModel.class);
if (view != null) {
getListView().setPadding(0, 0, 0, (int) getResources().getDimension(R.dimen.global_padding_bottom));
@ -56,6 +63,21 @@ public class SettingsFragment extends PreferenceFragmentCompat {
return true;
});
findPreference("scan_library").setOnPreferenceClickListener(preference -> {
settingViewModel.launchScan(new ScanCallback() {
@Override
public void onError(Exception exception) {
Toast.makeText(requireContext(), exception.getMessage(), Toast.LENGTH_SHORT).show();
}
@Override
public void onSuccess(boolean isScanning, long count) {
Toast.makeText(requireContext(), "Scanning: counting " + count + " elements", Toast.LENGTH_SHORT).show();
}
});
return true;
});
}
@Override

View file

@ -0,0 +1,51 @@
package com.cappielloantonio.play.viewmodel;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import com.cappielloantonio.play.interfaces.ScanCallback;
import com.cappielloantonio.play.repository.QueueRepository;
import com.cappielloantonio.play.repository.ScanRepository;
import com.cappielloantonio.play.repository.SongRepository;
public class SettingViewModel extends AndroidViewModel {
private static final String TAG = "SettingViewModel";
private ScanRepository scanRepository;
public SettingViewModel(@NonNull Application application) {
super(application);
scanRepository = new ScanRepository(application);
}
public void launchScan(ScanCallback callback) {
scanRepository.startScan(new ScanCallback() {
@Override
public void onError(Exception exception) {
callback.onError(exception);
}
@Override
public void onSuccess(boolean isScanning, long count) {
callback.onSuccess(isScanning, count);
}
});
}
public void getScanStatus(ScanCallback callback) {
scanRepository.getScanStatus(new ScanCallback() {
@Override
public void onError(Exception exception) {
callback.onError(exception);
}
@Override
public void onSuccess(boolean isScanning, long count) {
callback.onSuccess(isScanning, count);
}
});
}
}

View file

@ -28,6 +28,10 @@
app:title="@string/theme_selection"
app:useSimpleSummaryProvider="true" />
<Preference
android:key="scan_library"
android:title="Scan library" />
<Preference
android:key="logout"
android:title="Log out" />