diff options
| author | Andrew Dolgov <noreply@fakecake.org> | 2014-10-17 00:06:56 +0400 |
|---|---|---|
| committer | Andrew Dolgov <noreply@fakecake.org> | 2014-10-17 00:06:56 +0400 |
| commit | 97cc96839d31b6cce59ec29a6681c6fe802552ee (patch) | |
| tree | 9f3b8df270095bc65c10cd7208d05b3dad4794b9 /src/org/fox/ttrss/offline/OfflineDownloadService.java | |
| parent | 5775c0d56b7c856b508bb34e478eef53c2460624 (diff) | |
initial
Diffstat (limited to 'src/org/fox/ttrss/offline/OfflineDownloadService.java')
| -rw-r--r-- | src/org/fox/ttrss/offline/OfflineDownloadService.java | 500 |
1 files changed, 0 insertions, 500 deletions
diff --git a/src/org/fox/ttrss/offline/OfflineDownloadService.java b/src/org/fox/ttrss/offline/OfflineDownloadService.java deleted file mode 100644 index 2d65c890..00000000 --- a/src/org/fox/ttrss/offline/OfflineDownloadService.java +++ /dev/null @@ -1,500 +0,0 @@ -package org.fox.ttrss.offline; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; - -import org.fox.ttrss.ApiRequest; -import org.fox.ttrss.OnlineActivity; -import org.fox.ttrss.R; -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.Feed; -import org.fox.ttrss.types.FeedCategory; -import org.fox.ttrss.util.DatabaseHelper; -import org.fox.ttrss.util.ImageCacheService; -import org.jsoup.Jsoup; -import org.jsoup.nodes.Document; -import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; - -import android.app.ActivityManager; -import android.app.ActivityManager.RunningServiceInfo; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteStatement; -import android.os.Binder; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.util.Log; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -public class OfflineDownloadService extends Service { - - private final String TAG = this.getClass().getSimpleName(); - - public static final int NOTIFY_DOWNLOADING = 1; - public static final String INTENT_ACTION_SUCCESS = "org.fox.ttrss.intent.action.DownloadComplete"; - public static final String INTENT_ACTION_CANCEL = "org.fox.ttrss.intent.action.Cancel"; - - private static final int OFFLINE_SYNC_SEQ = 50; - private static final int OFFLINE_SYNC_MAX = OFFLINE_SYNC_SEQ * 10; - - private SQLiteDatabase m_writableDb; - private SQLiteDatabase m_readableDb; - private int m_articleOffset = 0; - private String m_sessionId; - private NotificationManager m_nmgr; - - private boolean m_batchMode = false; - private boolean m_downloadInProgress = false; - private boolean m_downloadImages = false; - private int m_syncMax; - private SharedPreferences m_prefs; - private boolean m_canProceed = true; - - private final IBinder m_binder = new LocalBinder(); - - public class LocalBinder extends Binder { - OfflineDownloadService getService() { - return OfflineDownloadService.this; - } - } - - @Override - public IBinder onBind(Intent intent) { - return m_binder; - } - - @Override - public void onCreate() { - super.onCreate(); - m_nmgr = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); - m_prefs = PreferenceManager - .getDefaultSharedPreferences(getApplicationContext()); - - m_downloadImages = m_prefs.getBoolean("offline_image_cache_enabled", false); - m_syncMax = Integer.parseInt(m_prefs.getString("offline_sync_max", String.valueOf(OFFLINE_SYNC_MAX))); - - initDatabase(); - } - - @SuppressWarnings("deprecation") - private void updateNotification(String msg) { - Notification notification = new Notification(R.drawable.icon, - getString(R.string.notify_downloading_title), System.currentTimeMillis()); - - Intent intent = new Intent(this, OnlineActivity.class); - intent.setAction(INTENT_ACTION_CANCEL); - - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, - intent, 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)); - } - - private void downloadFailed() { - m_readableDb.close(); - m_writableDb.close(); - - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - // TODO send notification to activity? - - m_downloadInProgress = false; - stopSelf(); - } - - private boolean isCacheServiceRunning() { - ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); - for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { - if ("org.fox.ttrss.util.ImageCacheService".equals(service.service.getClassName())) { - return true; - } - } - return false; - } - - public void downloadComplete() { - m_downloadInProgress = false; - - // if cache service is running, it will send a finished intent on its own - if (!isCacheServiceRunning()) { - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - if (m_batchMode) { - - SharedPreferences localPrefs = getSharedPreferences("localprefs", Context.MODE_PRIVATE); - SharedPreferences.Editor editor = localPrefs.edit(); - editor.putBoolean("offline_mode_active", true); - editor.commit(); - - } else { - Intent intent = new Intent(); - intent.setAction(INTENT_ACTION_SUCCESS); - intent.addCategory(Intent.CATEGORY_DEFAULT); - sendBroadcast(intent); - } - } else { - updateNotification(getString(R.string.notify_downloading_images, 0)); - } - - m_readableDb.close(); - m_writableDb.close(); - - stopSelf(); - } - - private void initDatabase() { - DatabaseHelper dh = new DatabaseHelper(getApplicationContext()); - m_writableDb = dh.getWritableDatabase(); - m_readableDb = dh.getReadableDatabase(); - } - - /* private synchronized SQLiteDatabase getReadableDb() { - return m_readableDb; - } */ - - private synchronized SQLiteDatabase getWritableDb() { - return m_writableDb; - } - - @SuppressWarnings("unchecked") - private void downloadArticles() { - Log.d(TAG, "offline: downloading articles... offset=" + m_articleOffset); - - updateNotification(getString(R.string.notify_downloading_articles, m_articleOffset)); - - OfflineArticlesRequest req = new OfflineArticlesRequest(this); - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getHeadlines"); - put("sid", m_sessionId); - put("feed_id", "-4"); - put("view_mode", "unread"); - put("show_content", "true"); - put("skip", String.valueOf(m_articleOffset)); - put("limit", String.valueOf(OFFLINE_SYNC_SEQ)); - } - }; - - req.execute(map); - } - - private void downloadFeeds() { - - updateNotification(R.string.notify_downloading_feeds); - - getWritableDb().execSQL("DELETE FROM feeds;"); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - @Override - protected JsonElement doInBackground(HashMap<String, String>... params) { - JsonElement content = super.doInBackground(params); - - if (content != null) { - - try { - Type listType = new TypeToken<List<Feed>>() {}.getType(); - List<Feed> feeds = new Gson().fromJson(content, listType); - - SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO feeds " + - "("+BaseColumns._ID+", title, feed_url, has_icon, cat_id) " + - "VALUES (?, ?, ?, ?, ?);"); - - for (Feed feed : feeds) { - stmtInsert.bindLong(1, feed.id); - stmtInsert.bindString(2, feed.title); - stmtInsert.bindString(3, feed.feed_url); - stmtInsert.bindLong(4, feed.has_icon ? 1 : 0); - stmtInsert.bindLong(5, feed.cat_id); - - stmtInsert.execute(); - } - - stmtInsert.close(); - - Log.d(TAG, "offline: done downloading feeds"); - - m_articleOffset = 0; - - getWritableDb().execSQL("DELETE FROM articles;"); - } catch (Exception e) { - e.printStackTrace(); - updateNotification(R.string.offline_switch_error); - downloadFailed(); - } - } - - return content; - } - - @Override - protected void onPostExecute(JsonElement content) { - if (content != null) { - if (m_canProceed) { - downloadArticles(); - } else { - downloadFailed(); - } - } else { - updateNotification(getErrorMessage()); - downloadFailed(); - } - } - - }; - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getFeeds"); - put("sid", m_sessionId); - put("cat_id", "-3"); - put("unread_only", "true"); - } - }; - - req.execute(map); - } - - private void downloadCategories() { - - updateNotification(R.string.notify_downloading_feeds); - - getWritableDb().execSQL("DELETE FROM categories;"); - - ApiRequest req = new ApiRequest(getApplicationContext()) { - protected JsonElement doInBackground(HashMap<String, String>... params) { - JsonElement content = super.doInBackground(params); - - if (content != null) { - try { - Type listType = new TypeToken<List<FeedCategory>>() {}.getType(); - List<FeedCategory> cats = new Gson().fromJson(content, listType); - - SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO categories " + - "("+BaseColumns._ID+", title) " + - "VALUES (?, ?);"); - - for (FeedCategory cat : cats) { - stmtInsert.bindLong(1, cat.id); - stmtInsert.bindString(2, cat.title); - - stmtInsert.execute(); - } - - stmtInsert.close(); - - Log.d(TAG, "offline: done downloading categories"); - - } catch (Exception e) { - e.printStackTrace(); - updateNotification(R.string.offline_switch_error); - downloadFailed(); - } - } - - return content; - } - @Override - protected void onPostExecute(JsonElement content) { - if (content != null) { - if (m_canProceed) { - downloadFeeds(); - } else { - downloadFailed(); - } - } else { - updateNotification(getErrorMessage()); - downloadFailed(); - } - } - - }; - - @SuppressWarnings("serial") - HashMap<String,String> map = new HashMap<String,String>() { - { - put("op", "getCategories"); - put("sid", m_sessionId); - //put("cat_id", "-3"); - put("unread_only", "true"); - } - }; - - req.execute(map); - } - - - @Override - public void onDestroy() { - super.onDestroy(); - m_nmgr.cancel(NOTIFY_DOWNLOADING); - - m_canProceed = false; - Log.d(TAG, "onDestroy"); - - //m_readableDb.close(); - //m_writableDb.close(); - } - - public class OfflineArticlesRequest extends ApiRequest { - List<Article> m_articles; - - public OfflineArticlesRequest(Context context) { - super(context); - } - - @Override - protected JsonElement doInBackground(HashMap<String, String>... params) { - JsonElement content = super.doInBackground(params); - - if (content != null) { - - try { - Type listType = new TypeToken<List<Article>>() {}.getType(); - m_articles = new Gson().fromJson(content, listType); - - SQLiteStatement stmtInsert = getWritableDb().compileStatement("INSERT INTO articles " + - "("+BaseColumns._ID+", unread, marked, published, score, updated, is_updated, title, link, feed_id, tags, content, author) " + - "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); - - for (Article article : m_articles) { - - String tagsString = ""; - - for (String t : article.tags) { - tagsString += t + ", "; - } - - tagsString = tagsString.replaceAll(", $", ""); - - int index = 1; - stmtInsert.bindLong(index++, article.id); - stmtInsert.bindLong(index++, article.unread ? 1 : 0); - stmtInsert.bindLong(index++, article.marked ? 1 : 0); - stmtInsert.bindLong(index++, article.published ? 1 : 0); - stmtInsert.bindLong(index++, article.score); - stmtInsert.bindLong(index++, article.updated); - stmtInsert.bindLong(index++, article.is_updated ? 1 : 0); - stmtInsert.bindString(index++, article.title); - stmtInsert.bindString(index++, article.link); - stmtInsert.bindLong(index++, article.feed_id); - stmtInsert.bindString(index++, tagsString); // comma-separated tags - stmtInsert.bindString(index++, article.content); - stmtInsert.bindString(index++, article.author != null ? article.author : ""); - - if (m_downloadImages) { - Document doc = Jsoup.parse(article.content); - - if (doc != null) { - Elements images = doc.select("img"); - - for (Element img : images) { - String url = img.attr("src"); - - if (url.indexOf("://") != -1) { - if (!ImageCacheService.isUrlCached(OfflineDownloadService.this, url)) { - Intent intent = new Intent(OfflineDownloadService.this, - ImageCacheService.class); - - intent.putExtra("url", url); - startService(intent); - } - } - } - } - } - - try { - stmtInsert.execute(); - } catch (Exception e) { - e.printStackTrace(); - } - - } - - m_articleOffset += m_articles.size(); - - Log.d(TAG, "offline: received " + m_articles.size() + " articles; canProc=" + m_canProceed); - - stmtInsert.close(); - - } catch (Exception e) { - updateNotification(R.string.offline_switch_error); - Log.d(TAG, "offline: failed: exception when loading articles"); - e.printStackTrace(); - downloadFailed(); - } - - } - - return content; - } - - @Override - protected void onPostExecute(JsonElement content) { - if (content != null) { - - if (m_canProceed && m_articles != null) { - if (m_articles.size() == OFFLINE_SYNC_SEQ && m_articleOffset < m_syncMax) { - downloadArticles(); - } else { - downloadComplete(); - } - } else { - downloadFailed(); - } - - } else { - Log.d(TAG, "offline: failed: " + getErrorMessage()); - updateNotification(getErrorMessage()); - downloadFailed(); - } - } - } - - @Override - public void onStart(Intent intent, int startId) { - try { - if (getWritableDb().isDbLockedByCurrentThread() || getWritableDb().isDbLockedByOtherThreads()) { - return; - } - - m_sessionId = intent.getStringExtra("sessionId"); - m_batchMode = intent.getBooleanExtra("batchMode", false); - - if (!m_downloadInProgress) { - if (m_downloadImages) ImageCacheService.cleanupCache(this, false); - - updateNotification(R.string.notify_downloading_init); - m_downloadInProgress = true; - - downloadCategories(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } -} |