diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java index e4e955e5..71fc348a 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/DrawerFragment.java @@ -161,9 +161,11 @@ public class DrawerFragment extends Fragment implements RestApi.OnReceiveSystemI percentFormat.setMaximumFractionDigits(2); mCpuUsage.setText(percentFormat.format(info.cpuPercent / 100)); mRamUsage.setText(RestApi.readableFileSize(mActivity, info.sys)); + int announceTotal = info.discoveryMethods; + int announceConnected = announceTotal - info.discoveryErrors.size(); mAnnounceServer.setText(String.format(Locale.getDefault(), "%1$d/%2$d", - info.extAnnounceConnected, info.extAnnounceTotal)); - int color = (info.extAnnounceConnected > 0) + announceConnected, announceTotal)); + int color = (announceConnected > 0) ? R.color.text_green : R.color.text_red; mAnnounceServer.setTextColor(ContextCompat.getColor(getContext(), color)); diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java index 6de4fcba..3da5cda9 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderFragment.java @@ -11,16 +11,25 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.Log; -import android.view.*; -import android.widget.*; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.activities.FolderPickerActivity; import com.nutomic.syncthingandroid.activities.SettingsActivity; import com.nutomic.syncthingandroid.activities.SyncthingActivity; import com.nutomic.syncthingandroid.fragments.dialog.KeepVersionsDialogFragment; +import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.syncthing.RestApi; -import com.nutomic.syncthingandroid.syncthing.RestApi.SimpleVersioning; -import com.nutomic.syncthingandroid.syncthing.RestApi.Versioning; import com.nutomic.syncthingandroid.syncthing.SyncthingService; import com.nutomic.syncthingandroid.util.TextWatcherAdapter; @@ -58,7 +67,7 @@ public class FolderFragment extends Fragment private SyncthingService mSyncthingService; - private RestApi.Folder mFolder; + private Folder mFolder; private EditText mLabelView; private EditText mIdView; @@ -88,16 +97,18 @@ public class FolderFragment extends Fragment public void onCheckedChanged(CompoundButton view, boolean isChecked) { switch (view.getId()) { case R.id.master: - mFolder.readOnly = isChecked; + mFolder.type = (isChecked) ? "readonly" : "readwrite"; mFolderNeedsToUpdate = true; break; case R.id.device_toggle: + List devicesList = mFolder.getDevices(); RestApi.Device device = (RestApi.Device) view.getTag(); if (isChecked) { - mFolder.deviceIds.add(device.deviceID); + devicesList.add(device.deviceID); } else { - mFolder.deviceIds.remove(device.deviceID); + devicesList.remove(device.deviceID); } + mFolder.setDevices(devicesList); mFolderNeedsToUpdate = true; break; } @@ -109,11 +120,10 @@ public class FolderFragment extends Fragment @Override public void onValueChange(int intValue) { if (intValue == 0) { - mFolder.versioning = new Versioning(); + mFolder.versioning = new Folder.Versioning(); mVersioningKeepView.setText(R.string.off); } else { - mFolder.versioning = new SimpleVersioning(); - ((SimpleVersioning) mFolder.versioning).setParams(intValue); + mFolder.versioning.params.put("keep", valueOf(intValue)); mVersioningKeepView.setText(valueOf(intValue)); } mFolderNeedsToUpdate = true; @@ -143,7 +153,7 @@ public class FolderFragment extends Fragment if (mIsCreateMode) { if (savedInstanceState != null) { - mFolder = (RestApi.Folder) savedInstanceState.getSerializable("folder"); + mFolder = (Folder) savedInstanceState.getSerializable("folder"); } if (mFolder == null) { initFolder(); @@ -228,10 +238,10 @@ public class FolderFragment extends Fragment } if (!mIsCreateMode) { - List folders = mSyncthingService.getApi().getFolders(); + List folders = mSyncthingService.getApi().getFolders(); String passedId = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_ID); mFolder = null; - for (RestApi.Folder currentFolder : folders) { + for (Folder currentFolder : folders) { if (currentFolder.id.equals(passedId)) { mFolder = currentFolder; break; @@ -258,7 +268,7 @@ public class FolderFragment extends Fragment mLabelView.setText(mFolder.label); mIdView.setText(mFolder.id); mPathView.setText(mFolder.path); - mFolderMasterView.setChecked(mFolder.readOnly); + mFolderMasterView.setChecked(mFolder.type.equals("readonly")); List devicesList = mSyncthingService.getApi().getDevices(false); mDevicesContainer.removeAllViews(); @@ -270,10 +280,10 @@ public class FolderFragment extends Fragment } } - boolean versioningEnabled = mFolder.versioning instanceof SimpleVersioning; + boolean versioningEnabled = mFolder.versioning.type.equals("simple"); int versions = 0; if (versioningEnabled) { - versions = Integer.valueOf(mFolder.versioning.getParams().get("keep")); + versions = Integer.valueOf(mFolder.versioning.params.get("keep")); mVersioningKeepView.setText(valueOf(versions)); } else { mVersioningKeepView.setText(R.string.off); @@ -342,16 +352,16 @@ public class FolderFragment extends Fragment } private void initFolder() { - mFolder = new RestApi.Folder(); + mFolder = new Folder(); mFolder.id = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_ID); mFolder.label = getActivity().getIntent().getStringExtra(EXTRA_FOLDER_LABEL); mFolder.path = ""; mFolder.rescanIntervalS = 259200; // Scan every 3 days (in case inotify dropped some changes) - mFolder.deviceIds = new ArrayList<>(); - mFolder.versioning = new Versioning(); + mFolder.setDevices(new ArrayList<>()); + mFolder.versioning = new Folder.Versioning(); String deviceId = getActivity().getIntent().getStringExtra(EXTRA_DEVICE_ID); - if (deviceId != null) - mFolder.deviceIds.add(deviceId); + //if (deviceId != null) + // TODO mFolder.devices.add(deviceId); } private void prepareEditMode() { @@ -376,7 +386,7 @@ public class FolderFragment extends Fragment private void addDeviceViewAndSetListener(RestApi.Device device, LayoutInflater inflater) { inflater.inflate(R.layout.item_device_form, mDevicesContainer); SwitchCompat deviceView = (SwitchCompat) mDevicesContainer.getChildAt(mDevicesContainer.getChildCount()-1); - deviceView.setChecked(mFolder.deviceIds.contains(device.deviceID)); + deviceView.setChecked(mFolder.getDevices().contains(device.deviceID)); deviceView.setText(RestApi.getDeviceDisplayName(device)); deviceView.setTag(device); deviceView.setOnCheckedChangeListener(mCheckedListener); diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderListFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderListFragment.java index b7883aab..e269d3d2 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/FolderListFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/FolderListFragment.java @@ -13,6 +13,7 @@ import android.widget.AdapterView; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.activities.SettingsActivity; import com.nutomic.syncthingandroid.activities.SyncthingActivity; +import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.syncthing.RestApi; import com.nutomic.syncthingandroid.syncthing.SyncthingService; import com.nutomic.syncthingandroid.util.FoldersAdapter; @@ -32,7 +33,7 @@ public class FolderListFragment extends ListFragment implements SyncthingService /** * Compares folders by labels, uses the folder ID as fallback if the label is empty */ - private final static Comparator FOLDERS_COMPARATOR = (lhs, rhs) -> { + private final static Comparator FOLDERS_COMPARATOR = (lhs, rhs) -> { String lhsLabel = lhs.label != null && !lhs.label.isEmpty() ? lhs.label : lhs.id; String rhsLabel = rhs.label != null && !rhs.label.isEmpty() ? rhs.label : rhs.id; @@ -106,7 +107,7 @@ public class FolderListFragment extends ListFragment implements SyncthingService // Prevent scroll position reset due to list update from clear(). mAdapter.setNotifyOnChange(false); mAdapter.clear(); - List folders = activity.getApi().getFolders(); + List folders = activity.getApi().getFolders(); Collections.sort(folders, FOLDERS_COMPARATOR); mAdapter.addAll(folders); mAdapter.updateModel(activity.getApi()); diff --git a/src/main/java/com/nutomic/syncthingandroid/model/Folder.java b/src/main/java/com/nutomic/syncthingandroid/model/Folder.java new file mode 100644 index 00000000..647712f4 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/model/Folder.java @@ -0,0 +1,58 @@ +package com.nutomic.syncthingandroid.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class Folder implements Serializable { + + public String id; + public String label; + public String path; + public String type; + private transient List> devices; + public int rescanIntervalS; + public boolean ignorePerms; + public boolean autoNormalize; + public int minDiskFreePct; + public Versioning versioning; + public int copiers; + public int pullers; + public int hashers; + public String order; + public boolean ignoreDelete; + public int scanProgressIntervalS; + public int pullerSleepS; + public int pullerPauseS; + public int maxConflicts; + public boolean disableSparseFiles; + public boolean disableTempIndexes; + public String invalid; + + public static class Versioning implements Serializable { + public String type; + public Map params; + } + + public List getDevices() { + if (devices == null) + return new ArrayList<>(); + + List devicesList = new ArrayList<>(); + for (Map map : devices) { + devicesList.addAll(map.values()); + } + return devicesList; + } + + public void setDevices(List newDvices) { + devices.clear(); + for (String d : newDvices) { + Map map = new HashMap<>(); + map.put("deviceID", d); + devices.add(map); + } + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/EventProcessor.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/EventProcessor.java index 1a6c4137..c4c0552f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/EventProcessor.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/EventProcessor.java @@ -13,14 +13,12 @@ import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.util.Log; +import com.google.gson.JsonObject; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.activities.SettingsActivity; import com.nutomic.syncthingandroid.fragments.DeviceFragment; import com.nutomic.syncthingandroid.fragments.FolderFragment; -import org.json.JSONException; -import org.json.JSONObject; - import java.io.File; import java.util.concurrent.TimeUnit; @@ -70,7 +68,7 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene // If that's the case we've to start at zero because syncthing was restarted. mApi.getEvents(0, 1, new RestApi.OnReceiveEventListener() { @Override - public void onEvent(String eventType, JSONObject data) throws JSONException { + public void onEvent(String eventType, JsonObject data) { } @@ -89,10 +87,10 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene * Performs the actual event handling. */ @Override - public void onEvent(String type, JSONObject data) throws JSONException { + public void onEvent(String type, JsonObject data) { switch (type) { case "DeviceRejected": - String deviceId = data.getString("device"); + String deviceId = data.get("device").getAsString(); Log.d(TAG, "Unknwon device " + deviceId + " wants to connect"); Intent intent = new Intent(mContext, SettingsActivity.class) @@ -110,9 +108,9 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene notify(title, pi); break; case "FolderRejected": - deviceId = data.getString("device"); - String folderId = data.getString("folder"); - String folderLabel = data.getString("folderLabel"); + deviceId = data.get("device").getAsString(); + String folderId = data.get("folder").getAsString(); + String folderLabel = data.get("folderLabel").getAsString(); Log.d(TAG, "Device " + deviceId + " wants to share folder " + folderId); intent = new Intent(mContext, SettingsActivity.class) @@ -137,7 +135,8 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene notify(title, pi); break; case "ItemFinished": - File updatedFile = new File(data.getString("folderpath"), data.getString("item")); + File updatedFile = new File(data.get("folderpath").getAsString(), + data.get("item").getAsString()); Log.i(TAG, "Notified media scanner about " + updatedFile.toString()); mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(updatedFile))); diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java index db6b7864..4feb6c19 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java @@ -11,15 +11,21 @@ import android.support.annotation.NonNull; import android.text.TextUtils; import android.util.Log; import android.widget.Toast; + import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; -import com.google.gson.annotations.SerializedName; import com.nutomic.syncthingandroid.BuildConfig; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.activities.RestartActivity; import com.nutomic.syncthingandroid.http.GetTask; import com.nutomic.syncthingandroid.http.PostTask; +import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.util.FolderObserver; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -27,7 +33,11 @@ import org.json.JSONObject; import java.io.Serializable; import java.net.URL; import java.text.DecimalFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** @@ -76,60 +86,22 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, public static class SystemInfo { public long alloc; public double cpuPercent; - public int extAnnounceConnected; // Number of connected announce servers. - public int extAnnounceTotal; // Total number of configured announce servers. public int goroutines; public String myID; public long sys; + public boolean discoveryEnabled; + public int discoveryMethods; + public Map discoveryErrors; } public static class SystemVersion { - @SerializedName("arch") - public String architecture; - @SerializedName("codename") + public String arch; public String codename; - @SerializedName("longVersion") public String longVersion; - @SerializedName("os") public String os; - @SerializedName("version") public String version; } - public static class Folder implements Serializable { - public String path; - public String label; - public String id; - public String invalid; - public List deviceIds; - public boolean readOnly; - public int rescanIntervalS; - public Versioning versioning; - } - - public static class Versioning implements Serializable { - protected final Map mParams = new HashMap<>(); - - public String getType() { - return ""; - } - - public Map getParams() { - return mParams; - } - } - - public static class SimpleVersioning extends Versioning { - @Override - public String getType() { - return "simple"; - } - - public void setParams(int keep) { - mParams.put("keep", Integer.toString(keep)); - } - } - public static class Connection { public String at; public long inBytesTotal; @@ -240,15 +212,10 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, if (s == null) return; - try { - JSONObject json = new JSONObject(s); - mVersion = json.getString("version"); - Log.i(TAG, "Syncthing version is " + mVersion); - tryIsAvailable(); - } - catch (JSONException e) { - Log.w(TAG, "Failed to parse config", e); - } + JsonObject json = new JsonParser().parse(s).getAsJsonObject(); + mVersion = json.get("version").getAsString(); + Log.i(TAG, "Syncthing version is " + mVersion); + tryIsAvailable(); } }.execute(); new GetTask(mUrl, GetTask.URI_CONFIG, mHttpsCertPath, mApiKey) { @@ -448,26 +415,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, if (s == null) return; - try { - JSONObject system = new JSONObject(s); - SystemInfo si = new SystemInfo(); - si.alloc = system.getLong("alloc"); - si.cpuPercent = system.getDouble("cpuPercent"); - if (system.has("discoveryEnabled")) { - si.extAnnounceTotal = system.getInt("discoveryMethods"); - si.extAnnounceConnected = - si.extAnnounceTotal - system.getJSONObject("discoveryErrors").length(); - } else { - si.extAnnounceTotal = 0; - si.extAnnounceConnected = 0; - } - si.goroutines = system.getInt("goroutines"); - si.myID = system.getString("myID"); - si.sys = system.getLong("sys"); - listener.onReceiveSystemInfo(si); - } catch (JSONException e) { - Log.w(TAG, "Failed to read system info", e); - } + listener.onReceiveSystemInfo(new Gson().fromJson(s, SystemInfo.class)); } }.execute(); } @@ -502,45 +450,13 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, if (mConfig == null) return new ArrayList<>(); - List ret; try { - JSONArray folders = mConfig.getJSONArray("folders"); - ret = new ArrayList<>(folders.length()); - for (int i = 0; i < folders.length(); i++) { - JSONObject json = folders.getJSONObject(i); - Folder r = new Folder(); - r.path = json.getString("path"); - r.label = json.getString("label"); - r.id = json.getString("id"); - // TODO: Field seems to be missing sometimes. - // https://github.com/syncthing/syncthing-android/issues/291 - r.invalid = json.optString("invalid"); - r.deviceIds = new ArrayList<>(); - JSONArray devices = json.getJSONArray("devices"); - for (int j = 0; j < devices.length(); j++) { - JSONObject n = devices.getJSONObject(j); - r.deviceIds.add(n.getString("deviceID")); - } - - r.readOnly = json.getString("type").equals("readonly"); - r.rescanIntervalS = json.getInt("rescanIntervalS"); - JSONObject versioning = json.getJSONObject("versioning"); - if (versioning.getString("type").equals("simple")) { - SimpleVersioning sv = new SimpleVersioning(); - JSONObject params = versioning.getJSONObject("params"); - sv.setParams(params.getInt("keep")); - r.versioning = sv; - } else { - r.versioning = new Versioning(); - } - - ret.add(r); - } + String foldersJson = mConfig.getJSONArray("folders").toString(); + return Arrays.asList(new Gson().fromJson(foldersJson, Folder[].class)); } catch (JSONException e) { Log.w(TAG, "Failed to read devices", e); return new ArrayList<>(); } - return ret; } /** @@ -662,12 +578,11 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, boolean isShared = false; outerloop: for (Folder r : getFolders()) { - for (String n : r.deviceIds) { + for (String n : r.getDevices()) { if (n.equals(deviceId)) { isShared = true; break outerloop; } - } } if (isShared) { @@ -704,7 +619,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, * @param eventType Name of the event. (See Syncthing documentation) * @param data Contains the data fields of the event. */ - void onEvent(String eventType, JSONObject data) throws JSONException; + void onEvent(String eventType, JsonObject data); /** * Called after all available events have been processed. @@ -723,27 +638,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, if (s == null) return; - try { - JSONObject json = new JSONObject(s); - Model m = new Model(); - m.globalBytes = json.getLong("globalBytes"); - m.globalDeleted = json.getLong("globalDeleted"); - m.globalFiles = json.getLong("globalFiles"); - m.localBytes = json.getLong("localBytes"); - m.localDeleted = json.getLong("localDeleted"); - m.localFiles = json.getLong("localFiles"); - m.inSyncBytes = json.getLong("inSyncBytes"); - m.inSyncFiles = json.getLong("inSyncFiles"); - m.needBytes = json.getLong("needBytes"); - m.needFiles = json.getLong("needFiles"); - m.needDeletes = json.getLong("needDeletes"); - m.state = json.getString("state"); - m.invalid = json.optString("invalid"); - mCachedModelInfo.put(folderId, m); - listener.onReceiveModel(folderId, m); - } catch (JSONException e) { - Log.w(TAG, "Failed to read folder info", e); - } + Model m = new Gson().fromJson(s, Model.class); + mCachedModelInfo.put(folderId, m); + listener.onReceiveModel(folderId, m); } }.execute("folder", folderId); } @@ -782,35 +679,32 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, if (s == null) return; - try { - JSONArray jsonEvents = new JSONArray(s); - long lastId = 0; + JsonArray jsonEvents = new JsonParser().parse(s).getAsJsonArray(); + long lastId = 0; - for (int i = 0; i < jsonEvents.length(); i++) { - JSONObject json = jsonEvents.getJSONObject(i); - String type = json.getString("type"); - long id = json.getLong("id"); + for (int i = 0; i < jsonEvents.size(); i++) { + JsonObject json = jsonEvents.get(i).getAsJsonObject(); + String type = json.get("type").getAsString(); + long id = json.get("id").getAsLong(); - if (lastId < id) - lastId = id; + if (lastId < id) + lastId = id; - JSONObject data = json.optJSONObject("data"); + JsonObject data = null; + if (json.has("data")) + data = json.get("data").getAsJsonObject(); - // Add folder path to data. - if (data != null && data.has("folder")) { - String folder = data.getString("folder"); - String folderPath = getPathForFolder(folder); - data.put("folderpath", folderPath); - } - - listener.onEvent(type, data); + // Add folder path to data. + if (data != null && data.has("folder")) { + String folder = data.get("folder").getAsString(); + String folderPath = getPathForFolder(folder); + data.addProperty("folderpath", folderPath); } - listener.onDone(lastId); - } - catch (JSONException e) { - Log.w(TAG, "Failed to read events", e); + listener.onEvent(type, data); } + + listener.onDone(lastId); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "since", String.valueOf(sinceId), "limit", String.valueOf(limit)); @@ -913,21 +807,21 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, r.put("label", folder.label); r.put("id", folder.id); r.put("ignorePerms", true); - r.put("type", (folder.readOnly) ? "readonly" : "readwrite"); + r.put("type", folder.type); JSONArray devices = new JSONArray(); - for (String n : folder.deviceIds) { + for (String n : folder.getDevices()) { JSONObject element = new JSONObject(); element.put("deviceID", n); devices.put(element); } r.put("devices", devices); JSONObject versioning = new JSONObject(); - versioning.put("type", folder.versioning.getType()); + versioning.put("type", folder.versioning.type); JSONObject params = new JSONObject(); versioning.put("params", params); - for (String key : folder.versioning.getParams().keySet()) { - params.put(key, folder.versioning.getParams().get(key)); + for (String key : folder.versioning.params.keySet()) { + params.put(key, folder.versioning.params.get(key)); } r.put("rescanIntervalS", folder.rescanIntervalS); r.put("versioning", versioning); @@ -1002,16 +896,13 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, if (s == null) return; - String normalized = null; - String error = null; - try { - JSONObject json = new JSONObject(s); - normalized = json.optString("id", null); - error = json.optString("error", null); - } catch (JSONException e) { - Log.w(TAG, "Failed to parse normalized device ID JSON", e); - } - listener.onDeviceIdNormalized(normalized, error); + JsonObject json = new JsonParser().parse(s).getAsJsonObject(); + JsonElement id = json.get("id"); + JsonElement error = json.get("error"); + if (id != null) + listener.onDeviceIdNormalized(id.getAsString(), null); + if (error != null) + listener.onDeviceIdNormalized(null, error.getAsString()); } }.execute("id", id); } diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java index a5fa7597..1bf37c36 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java @@ -23,6 +23,7 @@ import android.widget.Toast; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.activities.MainActivity; import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask; +import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.util.ConfigXml; import com.nutomic.syncthingandroid.util.FolderObserver; import com.android.PRNGFixes; @@ -350,7 +351,7 @@ public class SyncthingService extends Service implements mCurrentState = State.ACTIVE; onApiChange(); new Thread(() -> { - for (RestApi.Folder r : mApi.getFolders()) { + for (Folder r : mApi.getFolders()) { try { mObservers.add(new FolderObserver(mApi, r)); } catch (FolderObserver.FolderNotExistingException e) { diff --git a/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java b/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java index 3711e847..de0b3d45 100644 --- a/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java +++ b/src/main/java/com/nutomic/syncthingandroid/util/FolderObserver.java @@ -3,6 +3,7 @@ package com.nutomic.syncthingandroid.util; import android.os.FileObserver; import android.util.Log; +import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.syncthing.RestApi; import java.io.File; @@ -17,7 +18,7 @@ public class FolderObserver extends FileObserver { private final OnFolderFileChangeListener mListener; - private final RestApi.Folder mFolder; + private final Folder mFolder; private final String mPath; @@ -27,7 +28,7 @@ public class FolderObserver extends FileObserver { public void onFolderFileChange(String folderId, String relativePath); } - public FolderObserver(OnFolderFileChangeListener listener, RestApi.Folder folder) + public FolderObserver(OnFolderFileChangeListener listener, Folder folder) throws FolderNotExistingException { this(listener, folder, ""); } @@ -53,7 +54,7 @@ public class FolderObserver extends FileObserver { * @param folder The folder where this folder belongs to. * @param path path to the monitored folder, relative to folder root. */ - private FolderObserver(OnFolderFileChangeListener listener, RestApi.Folder folder, String path) + private FolderObserver(OnFolderFileChangeListener listener, Folder folder, String path) throws FolderNotExistingException { super(folder.path + "/" + path, ATTRIB | CLOSE_WRITE | CREATE | DELETE | DELETE_SELF | MOVED_FROM | diff --git a/src/main/java/com/nutomic/syncthingandroid/util/FoldersAdapter.java b/src/main/java/com/nutomic/syncthingandroid/util/FoldersAdapter.java index 2c9461b6..49ed156e 100644 --- a/src/main/java/com/nutomic/syncthingandroid/util/FoldersAdapter.java +++ b/src/main/java/com/nutomic/syncthingandroid/util/FoldersAdapter.java @@ -12,6 +12,7 @@ import android.widget.TextView; import com.nutomic.syncthingandroid.BuildConfig; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.syncthing.RestApi; import java.util.HashMap; @@ -23,7 +24,7 @@ import static com.nutomic.syncthingandroid.syncthing.RestApi.readableFileSize; /** * Generates item views for folder items. */ -public class FoldersAdapter extends ArrayAdapter +public class FoldersAdapter extends ArrayAdapter implements RestApi.OnReceiveModelListener { private final HashMap mModels = new HashMap<>(); @@ -47,7 +48,7 @@ public class FoldersAdapter extends ArrayAdapter TextView size = (TextView) convertView.findViewById(R.id.size); TextView invalid = (TextView) convertView.findViewById(R.id.invalid); - RestApi.Folder folder = getItem(position); + Folder folder = getItem(position); RestApi.Model model = mModels.get(folder.id); label.setText(TextUtils.isEmpty(folder.label) ? folder.id : folder.label); state.setTextColor(ContextCompat.getColor(getContext(), R.color.text_green));