package kr.kdev.dg1s.biowiki.ui.notifications;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import com.android.volley.VolleyError;
import com.google.android.gcm.GCMRegistrar;
import com.google.gson.Gson;
import com.google.gson.internal.StringMap;
import com.wordpress.rest.RestRequest;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.InflaterInputStream;
import kr.kdev.dg1s.biowiki.BioWiki;
import kr.kdev.dg1s.biowiki.BuildConfig;
import kr.kdev.dg1s.biowiki.models.Note;
import kr.kdev.dg1s.biowiki.util.AppLog;
import kr.kdev.dg1s.biowiki.util.DeviceUtils;
import kr.kdev.dg1s.biowiki.util.MapUtils;
public class NotificationUtils {
public static final String WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS = "wp_pref_notification_settings";
public static final String WPCOM_PUSH_DEVICE_UUID = "wp_pref_notifications_uuid";
private static final String WPCOM_PUSH_DEVICE_SERVER_ID = "wp_pref_notifications_server_id";
public static void refreshNotifications(final RestRequest.Listener listener,
final RestRequest.ErrorListener errorListener) {
BioWiki.getRestClientUtils().getNotifications(new RestRequest.Listener() {
@Override
public void onResponse(JSONObject response) {
if (listener != null) {
listener.onResponse(response);
}
}
}, new RestRequest.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (errorListener != null) {
errorListener.onErrorResponse(error);
}
}
}
);
}
/*
* updates a single notification, storing the result in the local db upon success
*/
public static void updateNotification(final int noteId, final NoteUpdatedListener updateListener) {
if (noteId == 0)
return;
RestRequest.Listener listener = new RestRequest.Listener() {
@Override
public void onResponse(JSONObject jsonObject) {
if (jsonObject == null)
return;
final List<Note> notes;
try {
// response is an array of notes with a single note item
notes = parseNotes(jsonObject);
if (notes == null || notes.size() == 0) {
return;
}
} catch (JSONException e) {
AppLog.e(AppLog.T.NOTIFS, e);
return;
}
BioWiki.wpDB.addNote(notes.get(0), false);
if (updateListener != null) {
updateListener.onNoteUpdated(noteId);
}
}
};
BioWiki.getRestClientUtils().getNotification(Integer.toString(noteId), listener, null);
}
public static List<Note> parseNotes(JSONObject response) throws JSONException {
List<Note> notes;
JSONArray notesJSON = response.getJSONArray("notes");
notes = new ArrayList<Note>(notesJSON.length());
for (int i = 0; i < notesJSON.length(); i++) {
Note n = new Note(notesJSON.getJSONObject(i));
notes.add(n);
}
return notes;
}
public static String unzipString(byte[] zbytes) {
try {
// Add extra byte to array when Inflater is set to true
byte[] input = new byte[zbytes.length + 1];
System.arraycopy(zbytes, 0, input, 0, zbytes.length);
input[zbytes.length] = 0;
ByteArrayInputStream bin = new ByteArrayInputStream(input);
InflaterInputStream in = new InflaterInputStream(bin);
ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
int b;
while ((b = in.read()) != -1) {
bout.write(b);
}
bout.close();
return bout.toString();
} catch (IOException io) {
AppLog.e(AppLog.T.NOTIFS, "Unzipping failed", io);
return null;
}
}
public static void getPushNotificationSettings(Context context, RestRequest.Listener listener,
RestRequest.ErrorListener errorListener) {
if (/*!BioWiki.hasValidWPComCredentials(context)*/ true) {
return;
}
String gcmToken = GCMRegistrar.getRegistrationId(context);
if (TextUtils.isEmpty(gcmToken)) {
return;
}
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
String deviceID = settings.getString(WPCOM_PUSH_DEVICE_SERVER_ID, null);
if (TextUtils.isEmpty(deviceID)) {
AppLog.e(AppLog.T.NOTIFS, "device_ID is null in preferences. Get device settings skipped.");
return;
}
BioWiki.getRestClientUtils().get("/device/" + deviceID, listener, errorListener);
}
public static void setPushNotificationSettings(Context context) {
if (/*!BioWiki.hasValidWPComCredentials(context)*/ true) {
return;
}
String gcmToken = GCMRegistrar.getRegistrationId(context);
if (TextUtils.isEmpty(gcmToken)) {
return;
}
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
String deviceID = settings.getString(WPCOM_PUSH_DEVICE_SERVER_ID, null);
if (TextUtils.isEmpty(deviceID)) {
AppLog.e(AppLog.T.NOTIFS, "device_ID is null in preferences. Set device settings skipped.");
return;
}
String settingsJson = settings.getString(WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS, null);
if (settingsJson == null)
return;
Gson gson = new Gson();
Map<String, StringMap<String>> notificationSettings = gson.fromJson(settingsJson, HashMap.class);
Map<String, Object> updatedSettings = new HashMap<String, Object>();
if (notificationSettings == null)
return;
// Build the settings object to send back to WP.com
StringMap<?> mutedBlogsMap = notificationSettings.get("muted_blogs");
StringMap<?> muteUntilMap = notificationSettings.get("mute_until");
ArrayList<StringMap<Double>> blogsList = (ArrayList<StringMap<Double>>) mutedBlogsMap.get("value");
notificationSettings.remove("muted_blogs");
notificationSettings.remove("mute_until");
for (Map.Entry<String, StringMap<String>> entry : notificationSettings.entrySet()) {
StringMap<String> setting = entry.getValue();
updatedSettings.put(entry.getKey(), setting.get("value"));
}
if (muteUntilMap != null && muteUntilMap.get("value") != null) {
updatedSettings.put("mute_until", muteUntilMap.get("value"));
}
ArrayList<StringMap<Double>> mutedBlogsList = new ArrayList<StringMap<Double>>();
for (StringMap<Double> userBlog : blogsList) {
if (MapUtils.getMapBool(userBlog, "value")) {
mutedBlogsList.add(userBlog);
}
}
if (updatedSettings.size() == 0 && mutedBlogsList.size() == 0)
return;
updatedSettings.put("muted_blogs", mutedBlogsList); //If muted blogs list is unchanged we can even skip this assignment.
Map<String, String> contentStruct = new HashMap<String, String>();
contentStruct.put("device_token", gcmToken);
contentStruct.put("device_family", "android");
contentStruct.put("app_secret_key", NotificationUtils.getAppPushNotificationsName());
contentStruct.put("settings", gson.toJson(updatedSettings));
BioWiki.getRestClientUtils().post("/device/" + deviceID, contentStruct, null, null, null);
}
public static void registerDeviceForPushNotifications(final Context ctx, String token) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ctx);
String uuid = settings.getString(WPCOM_PUSH_DEVICE_UUID, null);
if (uuid == null)
return;
String deviceName = DeviceUtils.getInstance().getDeviceName(ctx);
Map<String, String> contentStruct = new HashMap<String, String>();
contentStruct.put("device_token", token);
contentStruct.put("device_family", "android");
contentStruct.put("app_secret_key", NotificationUtils.getAppPushNotificationsName());
contentStruct.put("device_name", deviceName);
contentStruct.put("device_model", Build.MANUFACTURER + " " + Build.MODEL);
contentStruct.put("app_version", BioWiki.versionName);
contentStruct.put("os_version", android.os.Build.VERSION.RELEASE);
contentStruct.put("device_uuid", uuid);
com.wordpress.rest.RestRequest.Listener listener = new RestRequest.Listener() {
@Override
public void onResponse(JSONObject jsonObject) {
AppLog.d(AppLog.T.NOTIFS, "Register token action succeeded");
try {
String deviceID = jsonObject.getString("ID");
if (deviceID == null) {
AppLog.e(AppLog.T.NOTIFS, "Server response is missing of the device_id. Registration skipped!!");
return;
}
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ctx);
SharedPreferences.Editor editor = settings.edit();
editor.putString(WPCOM_PUSH_DEVICE_SERVER_ID, deviceID);
JSONObject settingsJSON = jsonObject.getJSONObject("settings");
editor.putString(WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS, settingsJSON.toString());
editor.commit();
AppLog.d(AppLog.T.NOTIFS, "Server response OK. The device_id : " + deviceID);
} catch (JSONException e1) {
AppLog.e(AppLog.T.NOTIFS, "Server response is NOT ok. Registration skipped!!", e1);
}
}
};
RestRequest.ErrorListener errorListener = new RestRequest.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
AppLog.e(AppLog.T.NOTIFS, "Register token action failed", volleyError);
}
};
BioWiki.getRestClientUtils().post("/devices/new", contentStruct, null, listener, errorListener);
}
public static void unregisterDevicePushNotifications(final Context ctx) {
com.wordpress.rest.RestRequest.Listener listener = new RestRequest.Listener() {
@Override
public void onResponse(JSONObject jsonObject) {
AppLog.d(AppLog.T.NOTIFS, "Unregister token action succeeded");
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(ctx).edit();
editor.remove(WPCOM_PUSH_DEVICE_SERVER_ID);
editor.remove(WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS);
editor.remove(WPCOM_PUSH_DEVICE_UUID);
editor.commit();
}
};
RestRequest.ErrorListener errorListener = new RestRequest.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
AppLog.e(AppLog.T.NOTIFS, "Unregister token action failed", volleyError);
}
};
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(ctx);
String deviceID = settings.getString(WPCOM_PUSH_DEVICE_SERVER_ID, null);
if (TextUtils.isEmpty(deviceID)) {
return;
}
BioWiki.getRestClientUtils().post("/devices/" + deviceID + "/delete", listener, errorListener);
}
public static String getAppPushNotificationsName() {
//white listing only few keys.
if (BuildConfig.APP_PN_KEY.equals("kr.kdev.dg1s.biowiki.beta.build"))
return "kr.kdev.dg1s.biowiki.beta.build";
if (BuildConfig.APP_PN_KEY.equals("kr.kdev.dg1s.biowiki.debug.build"))
return "kr.kdev.dg1s.biowiki.debug.build";
return "kr.kdev.dg1s.biowiki.playstore";
}
static interface NoteUpdatedListener {
void onNoteUpdated(int noteId);
}
}