aboutsummaryrefslogtreecommitdiff
path: root/src/org/fox/ttrss/util
diff options
context:
space:
mode:
authorAndrew Dolgov <fox@fakecake.org>2012-09-16 13:25:28 +0400
committerAndrew Dolgov <fox@fakecake.org>2012-09-16 13:25:28 +0400
commitced80be1aea975b59db5a0e6dd14acb054e7910e (patch)
treef69f8c12151d0ccb9eee7f52d598c6ef626c914c /src/org/fox/ttrss/util
parent86a4f6c2dea5700ed3597d9afe280ddb93d56316 (diff)
initial
Diffstat (limited to 'src/org/fox/ttrss/util')
-rw-r--r--src/org/fox/ttrss/util/ApiRequest.java257
-rw-r--r--src/org/fox/ttrss/util/ImageCacheService.java208
2 files changed, 257 insertions, 208 deletions
diff --git a/src/org/fox/ttrss/util/ApiRequest.java b/src/org/fox/ttrss/util/ApiRequest.java
new file mode 100644
index 00000000..56901393
--- /dev/null
+++ b/src/org/fox/ttrss/util/ApiRequest.java
@@ -0,0 +1,257 @@
+package org.fox.ttrss.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+import org.fox.ttrss.R;
+import org.fox.ttrss.R.string;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+public class ApiRequest extends AsyncTask<HashMap<String,String>, Integer, JsonElement> {
+ private final String TAG = this.getClass().getSimpleName();
+
+ public enum ApiError { NO_ERROR, HTTP_UNAUTHORIZED, HTTP_FORBIDDEN, HTTP_NOT_FOUND,
+ HTTP_SERVER_ERROR, HTTP_OTHER_ERROR, SSL_REJECTED, PARSE_ERROR, IO_ERROR, OTHER_ERROR, API_DISABLED, API_UNKNOWN, LOGIN_FAILED, INVALID_URL, INCORRECT_USAGE };
+
+ public static final int API_STATUS_OK = 0;
+ public static final int API_STATUS_ERR = 1;
+
+ private String m_api;
+ private boolean m_trustAny = false;
+ private boolean m_transportDebugging = false;
+ protected int m_httpStatusCode = 0;
+ protected int m_apiStatusCode = 0;
+ protected Context m_context;
+ private SharedPreferences m_prefs;
+
+ protected ApiError m_lastError;
+
+ public ApiRequest(Context context) {
+ m_context = context;
+
+ m_prefs = PreferenceManager.getDefaultSharedPreferences(m_context);
+
+ m_api = m_prefs.getString("ttrss_url", null).trim();
+ m_trustAny = m_prefs.getBoolean("ssl_trust_any", false);
+ m_transportDebugging = m_prefs.getBoolean("transport_debugging", false);
+ m_lastError = ApiError.NO_ERROR;
+
+ }
+
+ protected int getErrorMessage() {
+ switch (m_lastError) {
+ case NO_ERROR:
+ return R.string.error_unknown;
+ case HTTP_UNAUTHORIZED:
+ return R.string.error_http_unauthorized;
+ case HTTP_FORBIDDEN:
+ return R.string.error_http_forbidden;
+ case HTTP_NOT_FOUND:
+ return R.string.error_http_not_found;
+ case HTTP_SERVER_ERROR:
+ return R.string.error_http_server_error;
+ case HTTP_OTHER_ERROR:
+ return R.string.error_http_other_error;
+ case SSL_REJECTED:
+ return R.string.error_ssl_rejected;
+ case PARSE_ERROR:
+ return R.string.error_parse_error;
+ case IO_ERROR:
+ return R.string.error_io_error;
+ case OTHER_ERROR:
+ return R.string.error_other_error;
+ case API_DISABLED:
+ return R.string.error_api_disabled;
+ case API_UNKNOWN:
+ return R.string.error_api_unknown;
+ case LOGIN_FAILED:
+ return R.string.error_login_failed;
+ case INVALID_URL:
+ return R.string.error_invalid_api_url;
+ case INCORRECT_USAGE:
+ return R.string.error_api_incorrect_usage;
+ default:
+ Log.d(TAG, "getErrorMessage: unknown error code=" + m_lastError);
+ return R.string.error_unknown;
+ }
+ }
+
+ @Override
+ protected JsonElement doInBackground(HashMap<String, String>... params) {
+
+ Gson gson = new Gson();
+
+ String requestStr = gson.toJson(new HashMap<String,String>(params[0]));
+
+ if (m_transportDebugging) Log.d(TAG, ">>> (" + requestStr + ") " + m_api);
+
+ AndroidHttpClient client = AndroidHttpClient.newInstance("Tiny Tiny RSS");
+
+ if (m_trustAny) {
+ client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", new EasySSLSocketFactory(), 443));
+ }
+
+ try {
+
+ HttpPost httpPost;
+
+ try {
+ httpPost = new HttpPost(m_api + "/api/");
+ } catch (IllegalArgumentException e) {
+ m_lastError = ApiError.INVALID_URL;
+ e.printStackTrace();
+ client.close();
+ return null;
+ } catch (Exception e) {
+ m_lastError = ApiError.OTHER_ERROR;
+ e.printStackTrace();
+ client.close();
+ return null;
+ }
+
+ HttpContext context = null;
+
+ String httpLogin = m_prefs.getString("http_login", "").trim();
+ String httpPassword = m_prefs.getString("http_password", "").trim();
+
+ if (httpLogin.length() > 0) {
+ if (m_transportDebugging) Log.d(TAG, "Using HTTP Basic authentication.");
+
+ URL targetUrl;
+ try {
+ targetUrl = new URL(m_api);
+ } catch (MalformedURLException e) {
+ m_lastError = ApiError.INVALID_URL;
+ e.printStackTrace();
+ client.close();
+ return null;
+ }
+
+ HttpHost targetHost = new HttpHost(targetUrl.getHost(), targetUrl.getPort(), targetUrl.getProtocol());
+ CredentialsProvider cp = new BasicCredentialsProvider();
+ context = new BasicHttpContext();
+
+ cp.setCredentials(
+ new AuthScope(targetHost.getHostName(), targetHost.getPort()),
+ new UsernamePasswordCredentials(httpLogin, httpPassword));
+
+ context.setAttribute(ClientContext.CREDS_PROVIDER, cp);
+ }
+
+ httpPost.setEntity(new StringEntity(requestStr, "utf-8"));
+ HttpResponse execute = client.execute(httpPost, context);
+
+ m_httpStatusCode = execute.getStatusLine().getStatusCode();
+
+ switch (m_httpStatusCode) {
+ case 200:
+ InputStream content = execute.getEntity().getContent();
+
+ BufferedReader buffer = new BufferedReader(
+ new InputStreamReader(content), 8192);
+
+ String s = "";
+ String response = "";
+
+ while ((s = buffer.readLine()) != null) {
+ response += s;
+ }
+
+ if (m_transportDebugging) Log.d(TAG, "<<< " + response);
+
+ JsonParser parser = new JsonParser();
+
+ JsonElement result = parser.parse(response);
+ JsonObject resultObj = result.getAsJsonObject();
+
+ m_apiStatusCode = resultObj.get("status").getAsInt();
+
+ client.close();
+
+ switch (m_apiStatusCode) {
+ case API_STATUS_OK:
+ return result.getAsJsonObject().get("content");
+ case API_STATUS_ERR:
+ JsonObject contentObj = resultObj.get("content").getAsJsonObject();
+ String error = contentObj.get("error").getAsString();
+
+ if (error.equals("LOGIN_ERROR")) {
+ m_lastError = ApiError.LOGIN_FAILED;
+ } else if (error.equals("API_DISABLED")) {
+ m_lastError = ApiError.API_DISABLED;
+ } else if (error.equals("NOT_LOGGED_IN")) {
+ m_lastError = ApiError.LOGIN_FAILED;
+ } else if (error.equals("INCORRECT_USAGE")) {
+ m_lastError = ApiError.INCORRECT_USAGE;
+ } else {
+ Log.d(TAG, "Unknown API error: " + error);
+ m_lastError = ApiError.API_UNKNOWN;
+ }
+ }
+
+ return null;
+ case 401:
+ m_lastError = ApiError.HTTP_UNAUTHORIZED;
+ break;
+ case 403:
+ m_lastError = ApiError.HTTP_FORBIDDEN;
+ break;
+ case 404:
+ m_lastError = ApiError.HTTP_NOT_FOUND;
+ break;
+ case 500:
+ m_lastError = ApiError.HTTP_SERVER_ERROR;
+ break;
+ default:
+ m_lastError = ApiError.HTTP_OTHER_ERROR;
+ break;
+ }
+
+ client.close();
+ return null;
+ } catch (javax.net.ssl.SSLPeerUnverifiedException e) {
+ m_lastError = ApiError.SSL_REJECTED;
+ e.printStackTrace();
+ } catch (IOException e) {
+ m_lastError = ApiError.IO_ERROR;
+ e.printStackTrace();
+ } catch (com.google.gson.JsonSyntaxException e) {
+ m_lastError = ApiError.PARSE_ERROR;
+ e.printStackTrace();
+ } catch (Exception e) {
+ m_lastError = ApiError.OTHER_ERROR;
+ e.printStackTrace();
+ }
+
+ client.close();
+ return null;
+ }
+}
diff --git a/src/org/fox/ttrss/util/ImageCacheService.java b/src/org/fox/ttrss/util/ImageCacheService.java
deleted file mode 100644
index 25c4aff0..00000000
--- a/src/org/fox/ttrss/util/ImageCacheService.java
+++ /dev/null
@@ -1,208 +0,0 @@
-package org.fox.ttrss.util;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-
-import org.fox.ttrss.MainActivity;
-import org.fox.ttrss.R;
-import org.fox.ttrss.offline.OfflineDownloadService;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningServiceInfo;
-import android.app.IntentService;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.Environment;
-
-public class ImageCacheService extends IntentService {
-
- private final String TAG = this.getClass().getSimpleName();
-
- public static final int NOTIFY_DOWNLOADING = 1;
-
- private static final String CACHE_PATH = "/data/org.fox.ttrss/image-cache/";
-
- private int m_imagesDownloaded = 0;
-
- private NotificationManager m_nmgr;
-
- public ImageCacheService() {
- super("ImageCacheService");
- }
-
- private boolean isDownloadServiceRunning() {
- ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
- if ("org.fox.ttrss.OfflineDownloadService".equals(service.service.getClassName())) {
- return true;
- }
- }
- return false;
- }
-
-
- @Override
- public void onCreate() {
- super.onCreate();
- m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
- }
-
- public static boolean isUrlCached(String url) {
- String hashedUrl = md5(url);
-
- File storage = Environment.getExternalStorageDirectory();
-
- File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png");
-
- return file.exists();
- }
-
- public static String getCacheFileName(String url) {
- String hashedUrl = md5(url);
-
- File storage = Environment.getExternalStorageDirectory();
-
- File file = new File(storage.getAbsolutePath() + CACHE_PATH + "/" + hashedUrl + ".png");
-
- return file.getAbsolutePath();
- }
-
- public static void cleanupCache(boolean deleteAll) {
- if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
- File storage = Environment.getExternalStorageDirectory();
- File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH);
-
- long now = new Date().getTime();
-
- if (cachePath.isDirectory()) {
- for (File file : cachePath.listFiles()) {
- if (deleteAll || now - file.lastModified() > 1000*60*60*24*7) {
- file.delete();
- }
- }
- }
- }
- }
-
- protected static String md5(String s) {
- try {
- MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
- digest.update(s.getBytes());
- byte messageDigest[] = digest.digest();
-
- StringBuffer hexString = new StringBuffer();
- for (int i=0; i<messageDigest.length; i++)
- hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
-
- return hexString.toString();
-
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- private InputStream getStream(String urlString) {
- try {
- URL url = new URL(urlString);
- URLConnection urlConnection = url.openConnection();
- urlConnection.setConnectTimeout(250);
- return urlConnection.getInputStream();
- } catch (Exception ex) {
- return null;
- }
- }
-
- private void updateNotification(String msg) {
- Notification notification = new Notification(R.drawable.icon,
- getString(R.string.notify_downloading_title), System.currentTimeMillis());
-
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
-
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
- notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
-
- notification.setLatestEventInfo(this, getString(R.string.notify_downloading_title), msg, contentIntent);
-
- m_nmgr.notify(NOTIFY_DOWNLOADING, notification);
- }
-
- /* private void updateNotification(int msgResId) {
- updateNotification(getString(msgResId));
- } */
-
- @Override
- protected void onHandleIntent(Intent intent) {
- String url = intent.getStringExtra("url");
-
- //Log.d(TAG, "got request to download URL=" + url);
-
- if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
- return;
-
- String hashedUrl = md5(url);
-
- File storage = Environment.getExternalStorageDirectory();
- File cachePath = new File(storage.getAbsolutePath() + CACHE_PATH);
- if (!cachePath.exists()) cachePath.mkdirs();
-
- if (cachePath.isDirectory() && hashedUrl != null) {
- File outputFile = new File(cachePath.getAbsolutePath() + "/" + hashedUrl + ".png");
-
- if (!outputFile.exists()) {
-
- //Log.d(TAG, "downloading to " + outputFile.getAbsolutePath());
-
- InputStream is = getStream(url);
-
- if (is != null) {
- try {
- FileOutputStream fos = new FileOutputStream(outputFile);
-
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = is.read(buffer)) != -1) {
- fos.write(buffer, 0, len);
- }
-
- fos.close();
- is.close();
-
- m_imagesDownloaded++;
-
- updateNotification(getString(R.string.notify_downloading_images, m_imagesDownloaded));
-
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
-
- if (!isDownloadServiceRunning()) {
- m_nmgr.cancel(NOTIFY_DOWNLOADING);
-
- Intent success = new Intent();
- success.setAction(OfflineDownloadService.INTENT_ACTION_SUCCESS);
- success.addCategory(Intent.CATEGORY_DEFAULT);
- sendBroadcast(success);
- }
- }
-
-}