package io.evercam; import io.evercam.unirest.http.HttpResponse; import io.evercam.unirest.http.JsonNode; import io.evercam.unirest.http.Unirest; import io.evercam.unirest.http.exceptions.UnirestException; import local.org.apache.http.client.ClientProtocolException; import local.org.apache.http.client.methods.HttpDelete; import local.org.apache.http.client.methods.HttpPatch; import local.org.apache.http.client.methods.HttpPost; import local.org.apache.http.entity.StringEntity; import local.org.apache.http.impl.client.DefaultHttpClient; import local.org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class Camera extends EvercamObject { static String URL = API.URL + "cameras"; static String MEDIA_URL = API.MEDIA_URL + "cameras"; Camera(JSONObject cameraJSONObject) { this.jsonObject = cameraJSONObject; } /** * Create a new camera owned by the authenticating user * * @param cameraDetail Evercam camera detail object that produced by CameraBuilder * @return Evercam camera object. * @throws EvercamException If camera is not successfully created. * @see CameraDetail * @see CameraBuilder */ public static Camera create(CameraDetail cameraDetail) throws EvercamException { Camera camera = null; if (API.hasUserKeyPair()) { try { JSONObject cameraJSONObject = buildJSONObject(cameraDetail); DefaultHttpClient client = new DefaultHttpClient(); HttpPost post = new HttpPost(URL); post.setHeader("Content-type", "application/json"); post.setHeader("Accept", "application/json"); post.setEntity(new StringEntity(cameraJSONObject.toString())); local.org.apache.http.HttpResponse response = client.execute(post); String result = EntityUtils.toString(response.getEntity()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == CODE_UNAUTHORISED) { throw new EvercamException(EvercamException.MSG_INVALID_AUTH); } else if (statusCode == CODE_ERROR) { ErrorResponse errorResponse = new ErrorResponse(result); throw new EvercamException(errorResponse.getProperErrorMessage()); } else if (statusCode == CODE_CREATE || statusCode == CODE_OK) { JsonNode jsonNode = new JsonNode(result); JSONObject jsonObject = jsonNode.getObject().getJSONArray("cameras").getJSONObject(0); camera = new Camera(jsonObject); } else if (statusCode == CODE_SERVER_ERROR) { throw new EvercamException(EvercamException.MSG_SERVER_ERROR); } else if (statusCode == CODE_CONFLICT) { ErrorResponse errorResponse = new ErrorResponse(result); throw new EvercamException(errorResponse.getMessage()); } else if (statusCode == CODE_APPLICATION_ERROR) { throw new EvercamException("Application error"); } else { throw new EvercamException(statusCode + result); } } catch (JSONException e) { throw new EvercamException(e); } catch (ClientProtocolException e) { throw new EvercamException(e); } catch (IOException e) { throw new EvercamException(e); } } else { throw new EvercamException(EvercamException.MSG_USER_API_KEY_REQUIRED); } return camera; } /** * Delete a camera from Evercam along with any stored media. * * @param cameraId the unique identifier of the camera * @return If the camera delete is successful, return true, otherwise return false. * @throws EvercamException If camera not exists or user unauthorized */ public static boolean delete(String cameraId) throws EvercamException { if (API.hasUserKeyPair()) { try { DefaultHttpClient client = new DefaultHttpClient(); HttpDelete delete = new HttpDelete(URL + '/' + cameraId + '/' + "?api_key=" + API.getUserKeyPair()[0] + "&api_id=" + API.getUserKeyPair()[1]); delete.setHeader("Content-type", "application/json"); delete.setHeader("Accept", "application/json"); local.org.apache.http.HttpResponse response = client.execute(delete); String result = EntityUtils.toString(response.getEntity()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == CODE_OK) { return true; } else if (statusCode == CODE_UNAUTHORISED) { throw new EvercamException(EvercamException.MSG_INVALID_USER_KEY); } else if (statusCode == CODE_NOT_FOUND) { throw new EvercamException(result); } else if (statusCode == CODE_SERVER_ERROR) { throw new EvercamException(EvercamException.MSG_SERVER_ERROR); } else { return false; } } catch (ClientProtocolException e) { throw new EvercamException(e); } catch (IOException e) { throw new EvercamException(e); } } else { throw new EvercamException(EvercamException.MSG_USER_API_KEY_REQUIRED); } } /** * Updates full or partial data for an existing camera * * @param cameraDetail Evercam camera detail object that produced by PatchCameraBuilder * @return Evercam camera object. * @throws EvercamException If user unauthorized or error occurred with Evercam * @see CameraDetail * @see PatchCameraBuilder */ public static Camera patch(CameraDetail cameraDetail) throws EvercamException { Camera camera = null; if (API.hasUserKeyPair()) { try { JSONObject cameraJSONObject = buildJSONObject(cameraDetail); DefaultHttpClient client = new DefaultHttpClient(); HttpPatch patch = new HttpPatch(URL + '/' + cameraDetail.id); patch.setHeader("Content-type", "application/json"); patch.setHeader("Accept", "application/json"); patch.setEntity(new StringEntity(cameraJSONObject.toString())); local.org.apache.http.HttpResponse response = client.execute(patch); String result = EntityUtils.toString(response.getEntity()); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == CODE_UNAUTHORISED || statusCode == CODE_FORBIDDEN) { throw new EvercamException(EvercamException.MSG_INVALID_AUTH); } else if (statusCode == CODE_ERROR) { // try { ErrorResponse errorResponse = new ErrorResponse(result); String message = errorResponse.getMessage(); throw new EvercamException(message); /* JsonNode resultJsonObj = new JsonNode(result); Iterator keyIterator = resultJsonObj.getArray().getJSONObject(0).optJSONObject("message").keys(); String key = null; while(keyIterator.hasNext()){ key = (String)keyIterator.next(); } String errorMessageString = resultJsonObj.getArray().getJSONObject(0).optJSONObject("message").getJSONArray(key).getString(0); if (errorMessageString != null || !errorMessageString.isEmpty()){ // ErrorResponse errorResponse = new ErrorResponse(result.getBody().getObject()); throw new EvercamException(errorMessageString); }else { ErrorResponse errorResponse = new ErrorResponse(result); String message = errorResponse.getMessage(); throw new EvercamException(message); }*/ // }catch (JSONException e){ // throw new EvercamException("Something went wrong. Please try again."); // } // ErrorResponse errorResponse = new ErrorResponse(result); // String message = errorResponse.getMessage(); // throw new EvercamException(message); } else if (statusCode == CODE_OK) { JsonNode jsonNode = new JsonNode(result); JSONObject jsonObject = jsonNode.getObject().getJSONArray("cameras").getJSONObject(0); camera = new Camera(jsonObject); } else if (statusCode == CODE_SERVER_ERROR) { throw new EvercamException(EvercamException.MSG_SERVER_ERROR); } else { throw new EvercamException(statusCode + " " + result); } } catch (JSONException e) { throw new EvercamException(e); } catch (ClientProtocolException e) { throw new EvercamException(e); } catch (IOException e) { throw new EvercamException(e); } } else { throw new EvercamException(EvercamException.MSG_USER_API_KEY_REQUIRED); } return camera; } /** * Fetch details of a camera from Evercam by camera unique identifier * * @param cameraId the camera's unique identifier with Evercam * @param includeThumbnail set to true to get base64 encoded 150x150 thumbnail with camera view * @return Evercam camera object with all data of this camera * @throws EvercamException If user unauthorized or error occurred with Evercam */ public static Camera getById(String cameraId, boolean includeThumbnail) throws EvercamException { String url = URL + '/' + cameraId; Map<String, Object> map = new HashMap<String, Object>(); map.put("thumbnail", Boolean.toString(includeThumbnail)); ArrayList<Camera> cameraArrayList = getByUrl(url, map); return cameraArrayList.isEmpty() ? null : cameraArrayList.get(0); } /** * Returns the set of cameras associated with given conditions * API key pair has to be specified before calling this method * * @param userId unique Evercam username of the user, can be null * @param includeShared whether or not to include cameras shared with the user in the fetch. * @param includeThumbnail whether or not to get base64 encoded 150x150 thumbnail with camera view for each camera * @return the camera list that associated with the specified user * @throws EvercamException */ public static ArrayList<Camera> getAll(String userId, boolean includeShared, boolean includeThumbnail) throws EvercamException { Map<String, Object> map = new HashMap<String, Object>(); map.put("include_shared", Boolean.toString(includeShared)); map.put("thumbnail", Boolean.toString(includeThumbnail)); if (userId != null) { map.put("user_id", userId); } return getByUrl(URL, map); } /** * Returns data for a specified set of cameras. * * @param idSetString comma separated list of camera identifiers for the cameras being queried. * @return the list of specified set of cameras * @throws EvercamException If user unauthorized or error occurred with Evercam */ public static ArrayList<Camera> getByIdSet(String idSetString) throws EvercamException { Map<String, Object> map = new HashMap<String, Object>(); map.put("ids", idSetString); return getByUrl(URL, map); } /** * Request camera live snapshot from Evercam. * * @param cameraId the camera's unique identifier * @return the stream of camera live image * @throws EvercamException */ public static InputStream getLiveSnapshot(String cameraId) throws EvercamException { InputStream inputStream; if (API.hasUserKeyPair()) { try { HttpResponse response = Unirest.get(URL + "/" + cameraId + "/live/snapshot.jpg").queryString(API.userKeyPairMap()) .asBinary(); inputStream = response.getRawBody(); } catch (UnirestException e) { throw new EvercamException(e); } } else { throw new EvercamException(EvercamException.MSG_USER_API_KEY_REQUIRED); } return inputStream; } /** * PUT /cameras/{id} * Transfers the ownership of a camera from one user to another * * @param cameraId The unique identifier for the camera. * @param userId The Evercam user name or email address for the new camera owner. * @throws EvercamException if user key and id not specified */ public static Camera transfer(String cameraId, String userId) throws EvercamException { Camera transferredCamera; if (API.hasUserKeyPair()) { try { HttpResponse<JsonNode> response = Unirest.put(URL + '/' + cameraId) .queryString("user_id", userId).queryString(API.userKeyPairMap()).asJson(); JSONObject object = response.getBody().getObject(); if (response.getStatus() == CODE_OK) { transferredCamera = new Camera(object.getJSONArray("cameras").getJSONObject(0)); } else { ErrorResponse errorResponse = new ErrorResponse(object); String message = errorResponse.getMessage(); throw new EvercamException(message); } } catch (UnirestException e) { throw new EvercamException(e); } catch (JSONException e) { throw new EvercamException(e); } } else { throw new EvercamException(EvercamException.MSG_USER_API_KEY_REQUIRED); } return transferredCamera; } /** * Check if camera details contain username and password or not. * * @return True if username and password exists in camera model, otherwise return False. */ public boolean hasCredentials() { //FIXME: Should be replace by a better logic, for example by using 'owned' and 'rights' to tell the camera has credential parameters or not. return jsonObject.toString().contains("\"cam_username\":") && jsonObject.toString().contains("\"cam_password\":"); } /** * Return location object of this camera. * Return null if no location data associate with this camera. * * @see Location */ public Location getLocation() throws EvercamException { if (jsonObject.isNull("location")) { return null; } else { JSONObject locationJsonObject = getJsonObjectByString("location"); return new Location(locationJsonObject); } } public double getLat() throws EvercamException { if (jsonObject.isNull("location")) { return 0.0; } else { JSONObject locationJsonObject = getJsonObjectByString("location"); try { return (float) locationJsonObject.getDouble("lat"); } catch (JSONException e) { throw new EvercamException(e); } } } public double getLng() throws EvercamException { if (jsonObject.isNull("location")) { return 0.0; } else { JSONObject locationJsonObject = getJsonObjectByString("location"); try { return (float) locationJsonObject.getDouble("lng"); } catch (JSONException e) { throw new EvercamException(e); } } } /** * Return external host name of the camera, return an empty string if * the host name does not exist. * * @return external host name of the camera * @throws EvercamException */ public String getExternalHost() throws EvercamException { External externalObject = getExternalObject(); if (externalObject != null) { return externalObject.getHost(); } return ""; } /** * Return internal host name of the camera, return an empty string if * the host name does not exist. * * @return internal host name of the camera * @throws EvercamException */ public String getInternalHost() throws EvercamException { Internal internalObject = getInternalObject(); if (internalObject != null) { return internalObject.getHost(); } return ""; } /** * Return external HTTP port number of the camera, * return 0 if no internal HTTP port associated with this camera. * * @return external HTTP port of the camera * @throws EvercamException */ public int getExternalHttpPort() throws EvercamException { External externalObject = getExternalObject(); if (externalObject != null) { return externalObject.getHttp().getPort(); } return 0; } /** * Return internal HTTP port number of the camera, * return 0 if no internal HTTP port associated with this camera. * * @return internal HTTP port of the camera * @throws EvercamException */ public int getInternalHttpPort() throws EvercamException { Internal internalObject = getInternalObject(); if (internalObject != null) { return internalObject.getHttp().getPort(); } return 0; } /** * Return external RTSP port number of the camera, * return 0 if no external RTSP port associated with this camera. * * @return external RTSP port of the camera * @throws EvercamException */ public int getExternalRtspPort() throws EvercamException { External externalObject = getExternalObject(); if (externalObject != null) { return externalObject.getRtsp().getPort(); } return 0; } /** * Return internal RTSP port number of the camera, * return 0 if no internal RTSP port associated with this camera. * * @return internal RTSP port of the camera * @throws EvercamException */ public int getInternalRtspPort() throws EvercamException { Internal internalObject = getInternalObject(); if (internalObject != null) { return internalObject.getRtsp().getPort(); } return 0; } /** * Return camera's username. If no username associated with the camera, * return an empty string. */ public String getUsername() { return getStringNotNull("cam_username"); } /** * Return camera's password. If no password associated with the camera, * return an empty string. */ public String getPassword() { return getStringNotNull("cam_password"); } /** * Return unique Evercam identifier for the camera. * * @throws EvercamException */ public String getId() { try { return jsonObject.getString("id"); } catch (JSONException e) { return ""; } } /** * Return username of camera owner. * * @throws EvercamException */ public String getOwner() throws EvercamException { return getStringNotNull("owner"); } /** * Whether or not this camera is publically available. * * @return True if this camera is publically available, otherwise return false. * @throws EvercamException */ public boolean isPublic() throws EvercamException { try { return jsonObject.getBoolean("is_public"); } catch (JSONException e) { throw new EvercamException(e); } } /** * Whether the camera is publicly findable. * * @return True if the camera is publicly findable, otherwise return false. * @throws EvercamException */ public boolean isDiscoverable() throws EvercamException { try { return jsonObject.getBoolean("discoverable"); } catch (JSONException e) { throw new EvercamException(e); } } /** * Return human readable or friendly name for the camera. * * @throws EvercamException */ public String getName() throws EvercamException { try { return jsonObject.getString("name"); } catch (JSONException e) { throw new EvercamException(e); } } /** * Return unique identifier for the camera vendor. * * @throws EvercamException */ public String getVendorId() throws EvercamException { return getStringNotNull("vendor_id"); } /** * Return the name for the camera vendor. * * @throws EvercamException */ public String getVendorName() throws EvercamException { return getStringNotNull("vendor_name"); } /** * Return name of the IANA/tz timezone where this camera is located. * * @throws EvercamException */ public String getTimezone() throws EvercamException { try { return jsonObject.getString("timezone"); } catch (JSONException e) { throw new EvercamException(e); } } /** * Return the name of the camera model. * * @throws EvercamException */ public String getModelName() throws EvercamException { try { return jsonObject.getString("model_name"); } catch (JSONException e) { return ""; } } /** * Return the unique identifier of the camera model. * * @throws EvercamException */ public String getModelId() throws EvercamException { return getStringNotNull("model_id"); } /** * Return the physical network MAC address of the camera, return an * empty string if no MAC address associated with this camera. */ public String getMacAddress() { return getStringNotNull("mac_address"); } /** * Whether or not this camera is currently online. * * @return True if this camera is currently online, otherwise return false. */ public boolean isOnline() { try { return jsonObject.getBoolean("is_online"); } catch (JSONException e) { //Return false instead of throw a new exception //Because the exception occurs when online status is 'null'. return false; } } /** * Whether or not this camera is owned by the authenticated user. * * @return True if this camera is owned by this user, otherwise return false. * @throws EvercamException */ public boolean isOwned() throws EvercamException { try { return jsonObject.getBoolean("owned"); } catch (JSONException e) { throw new EvercamException(e); } } /** * Return internal web page URL for this camera. * Return an empty string if no internal url associated with this camera. */ public String getInternalCameraEndpoint() throws EvercamException { Internal internalObject = getInternalObject(); if (internalObject != null) { return internalObject.getHttp().getCameraUrl(); } return ""; } /** * Return external web page URL for this camera. * Return an empty string if no external url associated with this camera. */ public String getExternalCameraEndpoint() throws EvercamException { External externalObject = getExternalObject(); if (externalObject != null) { return externalObject.getHttp().getCameraUrl(); } return ""; } /** * Return internal full jpg URL of this camera that can be * used to request a camera live image. Return an empty string * if the URL does not exist. * * @return full internal snapshot URL (jpg) of this camera. * @throws EvercamException */ public String getInternalJpgUrl() throws EvercamException { Internal internalObject = getInternalObject(); if (internalObject != null) { return internalObject.getHttp().getJpgUrl(); } return ""; } /** * Return external full jpg URL of this camera that can be * used to request a camera live image. Return an empty string * if the URL does not exist. * * @return full external snapshot URL (jpg) of this camera. * @throws EvercamException */ public String getExternalJpgUrl() throws EvercamException { External externalObject = getExternalObject(); if (externalObject != null) { return externalObject.getHttp().getJpgUrl(); } return ""; } /** * Return internal RTSP stream (H264) URL of this camera for * video playing. Return an empty string if the URL does not exist. * * @return full internal stream URL (h264) of this camera. * @throws EvercamException */ public String getInternalH264Url() throws EvercamException { Internal internalObject = getInternalObject(); if (internalObject != null) { return internalObject.getRtsp().getH264Url(); } return ""; } /** * Return internal RTSP stream (H264) URL of this camera for * video playing. Return an empty string if the URL does not exist. * * @return full internal stream URL (h264) of this camera. * @throws EvercamException */ public String getExternalH264Url() throws EvercamException { External externalObject = getExternalObject(); if (externalObject != null) { return externalObject.getRtsp().getH264Url(); } return ""; } /** * Return the internal full stream URL (H264) with username and password * for the basic authentication of media player. * * @return the H264 URL with credentials. * @throws EvercamException */ public String getInternalH264UrlWithCredential() throws EvercamException { return replaceUrlWithCredential(getInternalH264Url(), RTSP_PREFIX); } /** * Return the external full stream URL (H264) with username and password * for the basic authentication of media player. * * @return the H264 URL with credentials. * @throws EvercamException */ public String getExternalH264UrlWithCredential() throws EvercamException { return replaceUrlWithCredential(getExternalH264Url(), RTSP_PREFIX); } /** * @param url the full URL without credentials. * @param prefix the prefix of the URL. * @return the full URL with credentials as prefix://username:password@host * @throws EvercamException */ private String replaceUrlWithCredential(String url, String prefix) throws EvercamException { if (!url.isEmpty() && url.startsWith(prefix)) { return url.replace(prefix, prefix + getUsername() + ":" + getPassword() + "@"); } else { return ""; } } /** * Request for response with a specified URL and credentials for basic authentication. * Return as InputStream. * * @param url snapshot URL of this camera * @param username username for this camera * @param password password for this camera * @throws EvercamException If error happen with the HTTP request. */ public static InputStream getStreamFromUrl(String url, String username, String password) throws EvercamException { InputStream inputStream; try { HttpResponse response = Unirest.get(url).basicAuth(username, password).asBinary(); inputStream = response.getRawBody(); } catch (UnirestException e) { throw new EvercamException(e); } return inputStream; } /** * Request camera live snapshot from Evercam. * Equivalent with static method Camera.getSnapshotByCameraId(String), * with camera identifier auto filled for this camera object. * * @return the stream of camera live image * @throws EvercamException */ public InputStream getLiveSnapshot() throws EvercamException { return getLiveSnapshot(getId()); } /** * Validate the specified URL in valid or not by send a HTTP request. * * @param url the URL that need to be validated. * @return True if get a valid response, otherwise return false. */ private boolean isValidUrl(String url) { try { HttpResponse response = Unirest.get(url).asBinary(); if (response.getStatus() != CODE_ERROR) { return true; } } catch (UnirestException e) { //do nothing e.printStackTrace(); } return false; } /** * Return The array list that contains internal and/or external endpoint URL * of this camera (http://host:port). */ public ArrayList<String> getEndpoints() { ArrayList<String> endpointsArray = new ArrayList<String>(); try { if (getInternalHost() != null && !getInternalHost().equals("null")) { String internalUrl = HTTP_PREFIX + getInternalHost() + ":" + getInternalHttpPort(); endpointsArray.add(internalUrl); } if (getExternalHost() != null && !getExternalHost().equals("null")) { String externalUrl = HTTP_PREFIX + getExternalHost() + ":" + getExternalHttpPort(); endpointsArray.add(externalUrl); } } catch (EvercamException e) { e.printStackTrace(); } return endpointsArray; } /** * Build camera's JSON object for API requests. * * @param cameraDetail the produced camera detail object * @return a JSON object with all details for the camera * @throws JSONException */ private static JSONObject buildJSONObject(CameraDetail cameraDetail) throws JSONException { JSONObject cameraJSONObject = new JSONObject(); cameraJSONObject.put("api_key", API.getUserKeyPair()[0]); cameraJSONObject.put("api_id", API.getUserKeyPair()[1]); cameraJSONObject.put("id", cameraDetail.id); if (cameraDetail.internalHost != null) { cameraJSONObject.put("internal_host", cameraDetail.internalHost); } if (cameraDetail.internalHttpPort == null) { cameraJSONObject.put("internal_http_port", ""); } else if (cameraDetail.internalHttpPort != 0) { cameraJSONObject.put("internal_http_port", cameraDetail.internalHttpPort); } if (cameraDetail.internalRtspPort == null) { cameraJSONObject.put("internal_rtsp_port", ""); } else if (cameraDetail.internalRtspPort != 0) { cameraJSONObject.put("internal_rtsp_port", cameraDetail.internalRtspPort); } if (cameraDetail.externalHost != null) { cameraJSONObject.put("external_host", cameraDetail.externalHost); } if (cameraDetail.externalHttpPort == null) { cameraJSONObject.put("external_http_port", ""); } else if (cameraDetail.externalHttpPort != 0) { cameraJSONObject.put("external_http_port", cameraDetail.externalHttpPort); } if (cameraDetail.externalRtspPort == null) { cameraJSONObject.put("external_rtsp_port", ""); } else if (cameraDetail.externalRtspPort != 0) { cameraJSONObject.put("external_rtsp_port", cameraDetail.externalRtspPort); } if (cameraDetail.jpgUrl != null) { cameraJSONObject.put("jpg_url", cameraDetail.jpgUrl); } if (cameraDetail.mjpgUrl != null) { cameraJSONObject.put("mjpg_url", cameraDetail.mjpgUrl); } if (cameraDetail.mpegUrl != null) { cameraJSONObject.put("mpeg_url", cameraDetail.mpegUrl); } if (cameraDetail.h264Url != null) { cameraJSONObject.put("h264_url", cameraDetail.h264Url); } if (cameraDetail.audioUrl != null) { cameraJSONObject.put("audio_url", cameraDetail.audioUrl); } if (cameraDetail.isPublic != null) { cameraJSONObject.put("is_public", cameraDetail.isPublic); } if (cameraDetail.isOnline != null) { cameraJSONObject.put("is_online", cameraDetail.isOnline); } if (cameraDetail.cameraUsername != null) { cameraJSONObject.put("cam_username", cameraDetail.cameraUsername); } if (cameraDetail.cameraPassword != null) { cameraJSONObject.put("cam_password", cameraDetail.cameraPassword); } if (cameraDetail.name != null) { cameraJSONObject.put("name", cameraDetail.name); } if (cameraDetail.model != null) { cameraJSONObject.put("model", cameraDetail.model); } if (cameraDetail.vendor != null) { cameraJSONObject.put("vendor", cameraDetail.vendor); } if (cameraDetail.timezone != null) { cameraJSONObject.put("timezone", cameraDetail.timezone); } if (cameraDetail.macAddress != null) { cameraJSONObject.put("mac_address", cameraDetail.macAddress); } if (cameraDetail.locationLat != null) { cameraJSONObject.put("location_lat", cameraDetail.locationLat); } if (cameraDetail.locationLng != null) { cameraJSONObject.put("location_lng", cameraDetail.locationLng); } if (cameraDetail.locationLatString != null) { cameraJSONObject.put("location_lat", cameraDetail.locationLatString); } if (cameraDetail.locationLngString != null) { cameraJSONObject.put("location_lng", cameraDetail.locationLngString); } if (cameraDetail.isDiscoverable != null) { cameraJSONObject.put("discoverable", cameraDetail.isDiscoverable); } return cameraJSONObject; } /** * Return the 'internal' object of this camera. * Return null if it's a shared camera with no internal details. */ public Internal getInternalObject() throws EvercamException { try { JSONObject internalJsonObject = getJsonObjectByString("internal"); return new Internal(internalJsonObject); } catch (EvercamException e) { return null; } } /** * Return the 'external' object of this camera. * Return null if it's a shared camera with no external details. */ public External getExternalObject() { try { JSONObject externalJsonObject = getJsonObjectByString("external"); return new External(externalJsonObject); } catch (EvercamException e) { return null; } } /** * Return the dynamic DNS object of this camera. */ public ProxyUrl getProxyUrl() { try { JSONObject proxyUrlJsonObject = getJsonObjectByString("proxy_url"); return new ProxyUrl(proxyUrlJsonObject); } catch (EvercamException e) { return null; } } /** * Return the authenticated user's rights on this camera * * @throws EvercamException if no rights associated with the camera */ public Right getRights() throws EvercamException { try { String rightsString = jsonObject.getString("rights"); return new Right(rightsString); } catch (JSONException e) { throw new EvercamException("No rights associated with this camera."); } } /** * Return the URL of latest snapshot thumbnail */ public String getThumbnailUrl() { final String THUMBNAIL_URL = MEDIA_URL + '/' + getId() + "/thumbnail"; if(API.hasUserKeyPair()) { String apiKey = API.getUserKeyPair()[0]; String apiId = API.getUserKeyPair()[1]; return THUMBNAIL_URL + "?api_id=" + apiId + "&api_key=" + apiKey; } return THUMBNAIL_URL; } /** * Get camera list by requesting a specified URL and parameters as a map */ private static ArrayList<Camera> getByUrl(String url, Map<String, Object> parameterMap) throws EvercamException { ArrayList<Camera> cameraList = new ArrayList<Camera>(); if (API.hasUserKeyPair()) { try { HttpResponse<JsonNode> response = Unirest.get(url).queryString(API.userKeyPairMap()).queryString(parameterMap) .header("accept", "application/json").asJson(); if (response.getStatus() == CODE_OK) { JSONArray camerasJSONArray = response.getBody().getObject().getJSONArray("cameras"); for (int count = 0; count < camerasJSONArray.length(); count++) { JSONObject cameraJSONObject = camerasJSONArray.getJSONObject(count); cameraList.add(new Camera(cameraJSONObject)); } } else { throw new EvercamException(response.getBody().toString()); } } catch (JSONException e) { throw new EvercamException(e); } catch (UnirestException e) { throw new EvercamException(e); } } else { throw new EvercamException(EvercamException.MSG_USER_API_KEY_REQUIRED); } return cameraList; } /** * Tests if given camera parameters are correct * * @param externalUrl External camera URL, in format http://ip:port * @param jpgUrl The snapshot URL ending * @param cameraUsername camera's username * @param cameraPassword camera's password * @return Return the snapshot if the snapshot is available, otherwise return null * @throws EvercamException */ public static Snapshot testSnapshot(String externalUrl, String jpgUrl, String cameraUsername, String cameraPassword, String vendor_id, String camera_exId) throws EvercamException { try { Map<String, Object> map = new HashMap<String, Object>(); map.put("external_url", externalUrl); map.put("jpg_url", jpgUrl); map.put("cam_username", cameraUsername); map.put("cam_password", cameraPassword); map.put("vendor_id",vendor_id); map.put("camera_exid",camera_exId); String URL = (MEDIA_URL + "/test"); HttpResponse<JsonNode> httpResponse = Unirest.post(URL).fields(map).asJson(); int statusCode = httpResponse.getStatus(); if (statusCode == CODE_OK) { return new Snapshot(httpResponse.getBody().getObject()); } else{ String message = httpResponse.getBody().getObject().getString("message"); throw new EvercamException(message); /* JSONObject object = ((JsonNode)httpResponse.getBody()).getObject(); ErrorResponse errorResponse = new ErrorResponse(object); String message = errorResponse.getMessage(); throw new EvercamException(message); */ } } catch (JSONException e) { throw new EvercamException(e); } catch (UnirestException e) { throw new EvercamException(e); } } }