diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java index f615992b3..55d14ce47 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/BaseMainActivity.java @@ -140,7 +140,7 @@ import fr.gouv.etalab.mastodon.sqlite.AccountDAO; import fr.gouv.etalab.mastodon.sqlite.InstancesDAO; import fr.gouv.etalab.mastodon.sqlite.SearchDAO; import fr.gouv.etalab.mastodon.sqlite.Sqlite; -import fr.gouv.etalab.mastodon.sqlite.TimelineCacheDAO; +import fr.gouv.etalab.mastodon.sqlite.TagsCacheDAO; import static fr.gouv.etalab.mastodon.asynctasks.ManageFiltersAsyncTask.action.GET_ALL_FILTER; import static fr.gouv.etalab.mastodon.helper.Helper.ADD_USER_INTENT; @@ -1240,8 +1240,9 @@ public abstract class BaseMainActivity extends BaseActivity if (dir.isDirectory()) { Helper.deleteDir(dir); } + //Remove cached tags + new TagsCacheDAO(BaseMainActivity.this,db).removeAll(); } catch (Exception ignored) {} - new TimelineCacheDAO(BaseMainActivity.this, db).removeAllStatus(TimelineCacheDAO.HOME_TIMELINE); } }); Toasty.success(BaseMainActivity.this, getString(R.string.toast_cache_clear,String.format("%s %s", String.format(Locale.getDefault(), "%.2f", finalCacheSize), getString(R.string.cache_units))), Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java index 69b5dc8c9..8a40d8524 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/activities/TootActivity.java @@ -630,7 +630,7 @@ public class TootActivity extends BaseActivity implements OnRetrieveSearcAccount pp_progress.setVisibility(View.VISIBLE); pp_actionBar.setVisibility(View.GONE); } - new RetrieveSearchAsyncTask(getApplicationContext(),search,TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new RetrieveSearchAsyncTask(getApplicationContext(),search,true, TootActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }else{ if( s.toString().charAt(0) == ':') mt = ePattern.matcher(s.toString().substring(currentCursorPosition- searchLength, currentCursorPosition)); diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostStatusAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostStatusAsyncTask.java index 2a80682a9..d5b68d840 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostStatusAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostStatusAsyncTask.java @@ -15,12 +15,21 @@ package fr.gouv.etalab.mastodon.asynctasks; import android.content.Context; +import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; +import android.util.Log; + import java.lang.ref.WeakReference; +import java.util.List; +import java.util.regex.Matcher; + import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; import fr.gouv.etalab.mastodon.client.Entities.Account; +import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnPostStatusActionInterface; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; +import fr.gouv.etalab.mastodon.sqlite.TagsCacheDAO; /** @@ -57,6 +66,35 @@ public class PostStatusAsyncTask extends AsyncTask { @Override protected void onPostExecute(Void result) { listener.onPostStatusAction(apiResponse); + //Search for tag with upper cases to store them locally + Log.v(Helper.TAG,"ici"); + Thread thread = new Thread() { + @Override + public void run() { + String content = status.getContent(); + if( content != null && content.length() > 0){ + SQLiteDatabase db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + Matcher matcher = Helper.hashtagPattern.matcher(content); + while (matcher.find()){ + int matchStart = matcher.start(1); + int matchEnd = matcher.end(); + //Get cached tags + List cachedTag = new TagsCacheDAO(contextReference.get(), db).getAll(); + String tag = content.substring(matchStart, matchEnd); + tag = tag.replace("#",""); + if( cachedTag == null){ + new TagsCacheDAO(contextReference.get(), db).insert(tag); + }else { + //If cache doesn't contain the tag and the tag has upper case + if(!cachedTag.contains(tag) && !tag.toLowerCase().equals(tag)){ + new TagsCacheDAO(contextReference.get(), db).insert(tag); + } + } + } + } + } + }; + thread.start(); } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java index 24f0274d8..3a86e6bb5 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveFeedsAsyncTask.java @@ -141,19 +141,6 @@ public class RetrieveFeedsAsyncTask extends AsyncTask { SQLiteDatabase db = Sqlite.getInstance(this.contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); switch (action){ case HOME: - /*if( !Helper.isConnectedToInternet(contextReference.get(), Helper.getLiveInstance(contextReference.get()))){ - new TimelineCacheDAO(contextReference.get(), db).cleanDoublon(); - List statuses = new TimelineCacheDAO(contextReference.get(), db).getAllCachedStatus(max_id); - if( statuses == null || statuses.size() == 0) - apiResponse = api.getHomeTimeline(max_id); - else{ - apiResponse = new APIResponse(); - apiResponse.setStatuses(statuses); - apiResponse.setMax_id(statuses.get(statuses.size()-1).getId()); - } - }else{ - apiResponse = api.getHomeTimeline(max_id); - }*/ apiResponse = api.getHomeTimeline(max_id); break; case LOCAL: diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAsyncTask.java index 571fc9ebb..fe09f60a4 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/RetrieveSearchAsyncTask.java @@ -15,13 +15,18 @@ package fr.gouv.etalab.mastodon.asynctasks; import android.content.Context; +import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import java.lang.ref.WeakReference; +import java.util.List; import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.Entities.Results; +import fr.gouv.etalab.mastodon.helper.Helper; import fr.gouv.etalab.mastodon.interfaces.OnRetrieveSearchInterface; +import fr.gouv.etalab.mastodon.sqlite.Sqlite; +import fr.gouv.etalab.mastodon.sqlite.TagsCacheDAO; /** @@ -36,6 +41,7 @@ public class RetrieveSearchAsyncTask extends AsyncTask { private OnRetrieveSearchInterface listener; private API api; private WeakReference contextReference; + private boolean tagsOnly = false; public RetrieveSearchAsyncTask(Context context, String query, OnRetrieveSearchInterface onRetrieveSearchInterface){ this.contextReference = new WeakReference<>(context); @@ -43,11 +49,38 @@ public class RetrieveSearchAsyncTask extends AsyncTask { this.listener = onRetrieveSearchInterface; } + public RetrieveSearchAsyncTask(Context context, String query, boolean tagsOnly, OnRetrieveSearchInterface onRetrieveSearchInterface){ + this.contextReference = new WeakReference<>(context); + this.query = query; + this.listener = onRetrieveSearchInterface; + this.tagsOnly = tagsOnly; + } @Override protected Void doInBackground(Void... params) { api = new API(this.contextReference.get()); - results = api.search(query); + if( !tagsOnly) + results = api.search(query); + else { + //search tags only + results = api.search(query); + SQLiteDatabase db = Sqlite.getInstance(contextReference.get(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); + List cachedTags = new TagsCacheDAO(contextReference.get(), db).getBy(query); + if( results.getHashtags() != null){ + //If cache contains matching tags + if( cachedTags != null){ + for(String apiTag: results.getHashtags()){ + //Cache doesn't contain the tags coming from the api (case insensitive) + if(!Helper.containsCaseInsensitive(apiTag, cachedTags)){ + cachedTags.add(apiTag); //It's added + } + } + results.setHashtags(cachedTags); + } + }else if( cachedTags != null) { + results.setHashtags(cachedTags); + } + } return null; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java index 209dcc756..1f3ff8c8e 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/Helper.java @@ -2917,4 +2917,13 @@ public class Helper { return index; } + + public static boolean containsCaseInsensitive(String s, List l){ + for (String string : l){ + if (string.equalsIgnoreCase(s)){ + return true; + } + } + return false; + } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java b/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java index 92d9c061e..afdc9b1b2 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/services/LiveNotificationService.java @@ -389,20 +389,6 @@ public class LiveNotificationService extends Service implements NetworkStateRece case "update": event = Helper.EventStreaming.UPDATE; status = API.parseStatuses(getApplicationContext(), new JSONObject(response.get("payload").toString())); - String instance = Helper.getLiveInstance(getApplicationContext()); - /*if(userId != null && instance != null && userId.equals(account.getId()) && instance.equals(account.getInstance())){ - SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); - List alreadyCached = new TimelineCacheDAO(getApplicationContext(), db).getAllStatus(TimelineCacheDAO.HOME_TIMELINE); - ArrayList cachedId = new ArrayList<>(); - if(alreadyCached != null){ - for(Status scache: alreadyCached){ - cachedId.add(scache.getId()); - } - } - if(!cachedId.contains(status.getId())){ - new TimelineCacheDAO(getApplicationContext(), db).insertStatus(TimelineCacheDAO.HOME_TIMELINE, status, account.getToken()); - } - }*/ status.setNew(true); b.putParcelable("data", status); break; diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java index bc84ba2b1..c28271e6c 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/Sqlite.java @@ -26,7 +26,7 @@ import android.database.sqlite.SQLiteOpenHelper; public class Sqlite extends SQLiteOpenHelper { - public static final int DB_VERSION = 17; + public static final int DB_VERSION = 18; public static final String DB_NAME = "mastodon_etalab_db"; public static SQLiteDatabase db; private static Sqlite sInstance; @@ -58,6 +58,9 @@ public class Sqlite extends SQLiteOpenHelper { //Table for timeline cache static final String TABLE_TIMELINE_CACHE = "TIMELINE_CACHE"; + //Table for tags cache + static final String TABLE_CACHE_TAGS = "CACHE_TAGS"; + static final String COL_USER_ID = "USER_ID"; static final String COL_USERNAME = "USERNAME"; @@ -186,17 +189,11 @@ public class Sqlite extends SQLiteOpenHelper { + COL_DATE + " TEXT NOT NULL)"; - private final String CREATE_TABLE_TIMELE_CACHE = "CREATE TABLE " + TABLE_TIMELINE_CACHE + " (" + + private final String CREATE_TABLE_CACHE_TAGS = "CREATE TABLE " + + TABLE_CACHE_TAGS + "(" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " - + COL_CACHED_ACTION + " INTEGER NOT NULL, "+ COL_INSTANCE + " TEXT NOT NULL, " + COL_USER_ID + " NOT NULL, " + COL_DATE_BACKUP + " TEXT NOT NULL, " - + COL_STATUS_ID + " TEXT NOT NULL, " + COL_URI + " TEXT NOT NULL, " + COL_URL + " TEXT NOT NULL, " - + COL_ACCOUNT + " TEXT NOT NULL, " + COL_IN_REPLY_TO_ID + " TEXT, " + COL_IN_REPLY_TO_ACCOUNT_ID + " TEXT," - + COL_REBLOG + " TEXT, " + COL_CONTENT + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL, " - + COL_EMOJIS + " TEXT, " + COL_REBLOGS_COUNT + " INTEGER NOT NULL, " + COL_FAVOURITES_COUNT + " INTEGER NOT NULL, " - + COL_REBLOGGED + " INTEGER, " + COL_FAVOURITED + " INTEGER, " + COL_MUTED + " INTEGER, " + COL_SENSITIVE + " INTEGER, " - + COL_SPOILER_TEXT + " TEXT, " + COL_VISIBILITY + " TEXT NOT NULL, " + COL_MEDIA_ATTACHMENTS + " TEXT," + COL_CARD + " TEXT," - + COL_MENTIONS + " TEXT, " + COL_TAGS + " TEXT, " + COL_APPLICATION + " TEXT," - + COL_LANGUAGE + " TEXT," + COL_PINNED + " INTEGER)"; + + COL_TAGS + " TEXT NOT NULL)"; public Sqlite(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); @@ -222,7 +219,7 @@ public class Sqlite extends SQLiteOpenHelper { db.execSQL(CREATE_UNIQUE_CACHE_INDEX); db.execSQL(CREATE_TABLE_INSTANCES); db.execSQL(CREATE_TABLE_PEERTUBE_FAVOURITES); - db.execSQL(CREATE_TABLE_TIMELE_CACHE); + db.execSQL(CREATE_TABLE_CACHE_TAGS); } @Override @@ -269,7 +266,9 @@ public class Sqlite extends SQLiteOpenHelper { if( oldVersion > 8) db.execSQL("ALTER TABLE " + TABLE_STATUSES_CACHE + " ADD COLUMN "+ COL_CARD + " TEXT"); case 16: - db.execSQL(CREATE_TABLE_TIMELE_CACHE); + case 17: + db.execSQL("DROP TABLE IF EXISTS '" + TABLE_TIMELINE_CACHE + "'"); + db.execSQL(CREATE_TABLE_CACHE_TAGS); default: break; } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java new file mode 100644 index 000000000..f6dd9ea6c --- /dev/null +++ b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TagsCacheDAO.java @@ -0,0 +1,102 @@ +package fr.gouv.etalab.mastodon.sqlite; +/* Copyright 2018 Thomas Schneider + * + * This file is a part of Mastalab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Mastalab; if not, + * see . */ + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Created by Thomas on 30/11/2018. + * Manage cache tags in DB + */ +public class TagsCacheDAO { + + private SQLiteDatabase db; + public Context context; + + public TagsCacheDAO(Context context, SQLiteDatabase db) { + //Creation of the DB with tables + this.context = context; + this.db = db; + } + + //------- INSERTIONS ------- + + /** + * Insert a tag in database + * @param tag String + */ + public void insert(String tag) { + ContentValues values = new ContentValues(); + values.put(Sqlite.COL_TAGS, tag); + try{ + db.insert(Sqlite.TABLE_CACHE_TAGS, null, values); + }catch (Exception ignored) {} + } + + /*** + * Remove all tags + */ + public void removeAll(){ + db.delete(Sqlite.TABLE_CACHE_TAGS, null, null); + } + + /** + * Returns all tags in db + * @return string tags List + */ + public List getAll(){ + try { + Cursor c = db.query(Sqlite.TABLE_CACHE_TAGS, null, null, null, null, null, Sqlite.COL_TAGS+ " ASC", null); + return cursorToTag(c); + } catch (Exception e) { + return null; + } + } + + /** + * Returns tags starting by "search" + * @return tags List + */ + public List getBy(String search){ + Cursor c = db.query(Sqlite.TABLE_CACHE_TAGS, null, Sqlite.COL_TAGS + " LIKE \"%" + search + "%\"", null, null, null, null, null); + return cursorToTag(c); + } + + /*** + * Method to hydrate tag from database + * @param c Cursor + * @return List + */ + private List cursorToTag(Cursor c){ + //No element found + if (c.getCount() == 0) + return null; + List tags = new ArrayList<>(); + while (c.moveToNext() ) { + tags.add(c.getString(c.getColumnIndex(Sqlite.COL_TAGS))); + } + //Close the cursor + c.close(); + //Tag list is returned + return tags; + } +} diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java b/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java deleted file mode 100644 index 395577a7b..000000000 --- a/app/src/main/java/fr/gouv/etalab/mastodon/sqlite/TimelineCacheDAO.java +++ /dev/null @@ -1,486 +0,0 @@ -package fr.gouv.etalab.mastodon.sqlite; -/* Copyright 2017 Thomas Schneider - * - * This file is a part of Mastalab - * - * This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 3 of the - * License, or (at your option) any later version. - * - * Mastalab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General - * Public License for more details. - * - * You should have received a copy of the GNU General Public License along with Mastalab; if not, - * see . */ - -import android.content.ContentValues; -import android.content.Context; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import fr.gouv.etalab.mastodon.client.Entities.Account; -import fr.gouv.etalab.mastodon.client.Entities.Status; -import fr.gouv.etalab.mastodon.helper.FilterToots; -import fr.gouv.etalab.mastodon.helper.Helper; - - -/** - * Created by Thomas on 18/11/2018. - * Manage timeline in cache - */ -public class TimelineCacheDAO { - - private SQLiteDatabase db; - public Context context; - - //Type of cache - public static int HOME_TIMELINE = 0; - - public TimelineCacheDAO(Context context, SQLiteDatabase db) { - //Creation of the DB with tables - this.context = context; - this.db = db; - } - - - /** - * Insert a status in database - * @param cacheType int cache type - * @param status Status - * @return boolean - */ - public long insertStatus(int cacheType, Status status, String token) { - - ContentValues values = new ContentValues(); - Account account = new AccountDAO(context, db).getAccountByToken(token); - String instance = Helper.getLiveInstance(context); - values.put(Sqlite.COL_USER_ID, account.getId()); - values.put(Sqlite.COL_CACHED_ACTION, cacheType); - values.put(Sqlite.COL_INSTANCE, instance); - values.put(Sqlite.COL_STATUS_ID, status.getId()); - values.put(Sqlite.COL_URI, status.getUri()); - values.put(Sqlite.COL_URL, status.getUrl()); - values.put(Sqlite.COL_ACCOUNT, Helper.accountToStringStorage(status.getAccount())); - values.put(Sqlite.COL_CARD, Helper.cardToStringStorage(status.getCard())); - values.put(Sqlite.COL_IN_REPLY_TO_ID, status.getIn_reply_to_id()); - values.put(Sqlite.COL_IN_REPLY_TO_ACCOUNT_ID, status.getIn_reply_to_account_id()); - values.put(Sqlite.COL_REBLOG, status.getReblog()!=null?Helper.statusToStringStorage(status.getReblog()):null); - values.put(Sqlite.COL_CONTENT, status.getContent()); - values.put(Sqlite.COL_EMOJIS, status.getEmojis()!=null?Helper.emojisToStringStorage(status.getEmojis()):null); - values.put(Sqlite.COL_REBLOGS_COUNT, status.getReblogs_count()); - values.put(Sqlite.COL_FAVOURITES_COUNT, status.getFavourites_count()); - values.put(Sqlite.COL_REBLOGGED, status.isReblogged()); - values.put(Sqlite.COL_FAVOURITED, status.isFavourited()); - values.put(Sqlite.COL_MUTED, status.isMuted()); - values.put(Sqlite.COL_CREATED_AT, Helper.dateToString(status.getCreated_at())); - values.put(Sqlite.COL_DATE_BACKUP, Helper.dateToString(new Date())); - values.put(Sqlite.COL_SENSITIVE, status.isSensitive()); - values.put(Sqlite.COL_SPOILER_TEXT, status.getSpoiler_text()); - values.put(Sqlite.COL_VISIBILITY, status.getVisibility()); - values.put(Sqlite.COL_MEDIA_ATTACHMENTS, status.getMedia_attachments()!=null?Helper.attachmentToStringStorage(status.getMedia_attachments()):null); - values.put(Sqlite.COL_MENTIONS, status.getMentions()!=null?Helper.mentionToStringStorage(status.getMentions()):null); - values.put(Sqlite.COL_TAGS, status.getTags()!=null?Helper.tagToStringStorage(status.getTags()):null); - values.put(Sqlite.COL_APPLICATION, status.getApplication()!=null?Helper.applicationToStringStorage(status.getApplication()):null); - values.put(Sqlite.COL_LANGUAGE, status.getLanguage()); - values.put(Sqlite.COL_PINNED, status.isPinned()); - - //Inserts cached status - long last_id; - try{ - last_id = db.insert(Sqlite.TABLE_TIMELINE_CACHE, null, values); - }catch (Exception e) { - last_id = -1; - e.printStackTrace(); - } - return last_id; - } - - //------- UPDATES ------- - - /** - * Update a Status cached in database - * @param status Status - * @return boolean - */ - public int updateStatus(int cacheType, Status status ) { - ContentValues values = new ContentValues(); - String instance = Helper.getLiveInstance(context); - values.put(Sqlite.COL_REBLOGS_COUNT, status.getReblogs_count()); - values.put(Sqlite.COL_FAVOURITES_COUNT, status.getFavourites_count()); - values.put(Sqlite.COL_REBLOGGED, status.isReblogged()); - values.put(Sqlite.COL_FAVOURITED, status.isFavourited()); - values.put(Sqlite.COL_MUTED, status.isMuted()); - values.put(Sqlite.COL_PINNED, status.isPinned()); - return db.update(Sqlite.TABLE_TIMELINE_CACHE, - values, Sqlite.COL_STATUS_ID + " = ? AND " + Sqlite.COL_INSTANCE + " = ? " + Sqlite.COL_CACHED_ACTION + " = ?", - new String[]{String.valueOf(status.getId()), instance, String.valueOf(cacheType)}); - } - - - //------- REMOVE ------- - - - public void cleanDoublon(){ - db.delete(Sqlite.TABLE_TIMELINE_CACHE, Sqlite.COL_ID + " NOT IN (" + - " SELECT MIN(" + Sqlite.COL_ID + ")" + - " FROM " + Sqlite.TABLE_TIMELINE_CACHE + - " GROUP BY " + Sqlite.COL_STATUS_ID + "," + Sqlite.COL_INSTANCE + ")", null); - } - - /*** - * Remove stored status - * @return int - */ - public int remove(int cacheType, Status status){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - return db.delete(Sqlite.TABLE_TIMELINE_CACHE, Sqlite.COL_CACHED_ACTION + " = \""+ cacheType +"\" AND " + Sqlite.COL_STATUS_ID + " = \"" + status.getId() + "\" AND " + Sqlite.COL_INSTANCE + " = \"" + instance + "\" AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null); - } - - /*** - * Remove stored status - * @return int - */ - public int remove(int cacheType, Status status, String userId, String instance){ - return db.delete(Sqlite.TABLE_TIMELINE_CACHE, Sqlite.COL_CACHED_ACTION + " = \""+ cacheType +"\" AND " + Sqlite.COL_STATUS_ID + " = \"" + status.getId() + "\" AND " + Sqlite.COL_INSTANCE + " = \"" + instance + "\" AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null); - } - - public int removeAllStatus(int cacheType){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - return db.delete(Sqlite.TABLE_TIMELINE_CACHE, Sqlite.COL_CACHED_ACTION + " = \""+ cacheType +"\" AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null); - } - - //------- GETTERS ------- - - /** - * Returns all cached Statuses in db depending of their cache type - * @return stored status List - */ - public List getAllStatus(int cacheType){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_CREATED_AT + " DESC", null); - return cursorToListStatuses(c); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Returns all cached Statuses in db depending prior to max_id - * @return stored status List - */ - public List getAllCachedStatus(String max_id){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + TimelineCacheDAO.HOME_TIMELINE+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "' AND " + Sqlite.COL_STATUS_ID +" < '" + max_id+ "'", null, null, null, Sqlite.COL_STATUS_ID + " DESC", "40"); - return cursorToListStatuses(c); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Returns all cached Statuses in db depending of their cache type - * @return stored status List - */ - public List getStatusFromID(int cacheType, FilterToots filterToots, String max_id){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - //That the basic selection for all toots - StringBuilder selection = new StringBuilder(Sqlite.COL_CACHED_ACTION + " = '" + cacheType + "' AND " + Sqlite.COL_INSTANCE + " = '" + instance + "' AND " + Sqlite.COL_USER_ID + " = '" + userId + "'"); - if( max_id != null) - selection.append(" AND " + Sqlite.COL_STATUS_ID + " < '").append(max_id).append("'"); - //BOOST - if(filterToots.getBoosts() == FilterToots.typeFilter.NONE) - selection.append(" AND (" + Sqlite.COL_REBLOG + " IS NULL OR " + Sqlite.COL_REBLOG + " = 'null')"); - else if(filterToots.getBoosts() == FilterToots.typeFilter.ONLY) - selection.append(" AND " + Sqlite.COL_REBLOG + " IS NOT NULL AND " + Sqlite.COL_REBLOG + " <> 'null'"); - //REPLIES - if(filterToots.getReplies() == FilterToots.typeFilter.NONE) - selection.append(" AND (" + Sqlite.COL_IN_REPLY_TO_ID + " IS NULL OR " + Sqlite.COL_IN_REPLY_TO_ID + " = 'null')"); - else if(filterToots.getReplies() == FilterToots.typeFilter.ONLY) - selection.append(" AND " + Sqlite.COL_IN_REPLY_TO_ID + " IS NOT NULL AND " + Sqlite.COL_IN_REPLY_TO_ID + " <> 'null'"); - //PINNED - if(filterToots.getPinned() == FilterToots.typeFilter.NONE) - selection.append(" AND " + Sqlite.COL_PINNED + " = 0"); - else if(filterToots.getPinned() == FilterToots.typeFilter.ONLY) - selection.append(" AND " + Sqlite.COL_PINNED + " = 1"); - //PINNED - if(filterToots.getMedia() == FilterToots.typeFilter.NONE) - selection.append(" AND " + Sqlite.COL_MEDIA_ATTACHMENTS + " = '[]'"); - else if(filterToots.getMedia() == FilterToots.typeFilter.ONLY) - selection.append(" AND " + Sqlite.COL_MEDIA_ATTACHMENTS + " <> '[]'"); - - if( !filterToots.isV_direct()) - selection.append(" AND " + Sqlite.COL_VISIBILITY + " <> 'direct'"); - if( !filterToots.isV_private()) - selection.append(" AND " + Sqlite.COL_VISIBILITY + " <> 'private'"); - if( !filterToots.isV_public()) - selection.append(" AND " + Sqlite.COL_VISIBILITY + " <> 'public'"); - if( !filterToots.isV_unlisted()) - selection.append(" AND " + Sqlite.COL_VISIBILITY + " <> 'unlisted'"); - - if( filterToots.getDateIni() != null) - selection.append(" AND " + Sqlite.COL_CREATED_AT + " >= '").append(filterToots.getDateIni()).append("'"); - - if( filterToots.getDateEnd() != null) - selection.append(" AND " + Sqlite.COL_CREATED_AT + " <= '").append(filterToots.getDateEnd()).append("'"); - - if( filterToots.getFilter() != null ){ - String[] keywords = filterToots.getFilter().split(" "); - selection.append(" AND ("); - int i = 0; - for(String kw: keywords){ - - if( i == 0 && keywords.length == 1) - selection.append(Sqlite.COL_CONTENT + " LIKE '%").append(kw).append("%'"); - else if( i == 0 && keywords.length > 1) - selection.append(Sqlite.COL_CONTENT + " LIKE '%").append(kw).append("%' OR "); - else if( i == keywords.length -1 ) - selection.append(Sqlite.COL_CONTENT + " LIKE '%").append(kw).append("%'"); - i++; - } - selection.append(")"); - } - - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, selection.toString(), null, null, null, Sqlite.COL_CREATED_AT + " DESC", "40"); - return cursorToListStatuses(c); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - /** - * Returns the last date of backup for a user depending of the type of cache - * @return Date - */ - public Date getLastDateCache(int cacheType){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_DATE_BACKUP + " DESC", "1"); - //No element found - if (c.getCount() == 0) - return null; - //Take the first element - c.moveToFirst(); - String date = c.getString(c.getColumnIndex(Sqlite.COL_DATE_BACKUP)); - c.close(); - return Helper.stringToDate(context, date); - } catch (Exception e) { - return null; - } - } - - /** - * Returns the smaller date - * @return Date - */ - public Date getSmallerDate(int cacheType){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_CREATED_AT + " ASC", "1"); - //No element found - if (c.getCount() == 0) - return null; - //Take the first element - c.moveToFirst(); - String date = c.getString(c.getColumnIndex(Sqlite.COL_CREATED_AT)); - c.close(); - return Helper.stringToDate(context, date); - } catch (Exception e) { - return null; - } - } - - /** - * Returns the smaller date - * @return Date - */ - public Date getGreaterDate(int cacheType){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_CREATED_AT + " DESC", "1"); - //No element found - if (c.getCount() == 0) - return null; - //Take the first element - c.moveToFirst(); - String date = c.getString(c.getColumnIndex(Sqlite.COL_CREATED_AT)); - c.close(); - return Helper.stringToDate(context, date); - } catch (Exception e) { - return null; - } - } - - /** - * Returns the last id of backup for a user depending of the type of cache - * @return Date - */ - public String getLastTootIDCache(int cacheType){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_INSTANCE + " = '" + instance+ "' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, Sqlite.COL_STATUS_ID + " DESC", "1"); - //No element found - if (c.getCount() == 0) - return null; - //Take the first element - c.moveToFirst(); - String last_id = c.getString(c.getColumnIndex(Sqlite.COL_STATUS_ID)); - c.close(); - return last_id; - } catch (Exception e) { - return null; - } - } - - /** - * Returns a cached status by id in db - * @return stored status StoredStatus - */ - public Status getStatus(int cacheType, String id){ - SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); - String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); - String instance = Helper.getLiveInstance(context); - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_STATUS_ID + " = '" + id + "' AND " + Sqlite.COL_INSTANCE + " = '" + instance +"' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, null, null); - return cursorToStoredStatus(c); - } catch (Exception e) { - return null; - } - } - - - /** - * Returns a cached status by id in db - * @return stored status StoredStatus - */ - public Status getStatus(int cacheType, String id, String userId, String instance){ - try { - Cursor c = db.query(Sqlite.TABLE_TIMELINE_CACHE, null, Sqlite.COL_CACHED_ACTION + " = '" + cacheType+ "' AND " + Sqlite.COL_STATUS_ID + " = '" + id + "' AND " + Sqlite.COL_INSTANCE + " = '" + instance +"' AND " + Sqlite.COL_USER_ID + " = '" + userId+ "'", null, null, null, null, null); - return cursorToStoredStatus(c); - } catch (Exception e) { - return null; - } - } - - - - - /*** - * Method to hydrate statuses from database - * @param c Cursor - * @return Status - */ - private Status cursorToStoredStatus(Cursor c){ - //No element found - if (c.getCount() == 0) - return null; - //Take the first element - c.moveToFirst(); - //New status - Status status = new Status(); - status.setId(c.getString(c.getColumnIndex(Sqlite.COL_STATUS_ID))); - status.setUri(c.getString(c.getColumnIndex(Sqlite.COL_URI))); - status.setUrl(c.getString(c.getColumnIndex(Sqlite.COL_URL))); - status.setAccount(Helper.restoreAccountFromString(c.getString(c.getColumnIndex(Sqlite.COL_ACCOUNT)))); - status.setCard(Helper.restoreCardFromString(c.getString(c.getColumnIndex(Sqlite.COL_CARD)))); - status.setIn_reply_to_id(c.getString(c.getColumnIndex(Sqlite.COL_IN_REPLY_TO_ID))); - status.setIn_reply_to_account_id(c.getString(c.getColumnIndex(Sqlite.COL_IN_REPLY_TO_ACCOUNT_ID))); - status.setReblog(Helper.restoreStatusFromString(c.getString(c.getColumnIndex(Sqlite.COL_REBLOG)))); - status.setContent(c.getString(c.getColumnIndex(Sqlite.COL_CONTENT))); - status.setCreated_at(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_CREATED_AT)))); - status.setEmojis(Helper.restoreEmojisFromString(c.getString(c.getColumnIndex(Sqlite.COL_EMOJIS)))); - status.setReblogs_count(c.getInt(c.getColumnIndex(Sqlite.COL_REBLOGS_COUNT))); - status.setFavourites_count(c.getInt(c.getColumnIndex(Sqlite.COL_FAVOURITES_COUNT))); - status.setReblogged(c.getInt(c.getColumnIndex(Sqlite.COL_REBLOGGED))==1); - status.setFavourited(c.getInt(c.getColumnIndex(Sqlite.COL_FAVOURITED))==1); - status.setMuted(c.getInt(c.getColumnIndex(Sqlite.COL_MUTED))==1); - status.setSensitive(c.getInt(c.getColumnIndex(Sqlite.COL_SENSITIVE))==1); - status.setPinned(c.getInt(c.getColumnIndex(Sqlite.COL_PINNED))==1); - status.setSpoiler_text(c.getString(c.getColumnIndex(Sqlite.COL_SPOILER_TEXT))); - status.setVisibility(c.getString(c.getColumnIndex(Sqlite.COL_VISIBILITY))); - status.setMedia_attachments(Helper.restoreAttachmentFromString(c.getString(c.getColumnIndex(Sqlite.COL_MEDIA_ATTACHMENTS)))); - status.setMentions(Helper.restoreMentionFromString(c.getString(c.getColumnIndex(Sqlite.COL_MENTIONS)))); - status.setTags(Helper.restoreTagFromString(c.getString(c.getColumnIndex(Sqlite.COL_TAGS)))); - status.setApplication(Helper.restoreApplicationFromString(c.getString(c.getColumnIndex(Sqlite.COL_APPLICATION)))); - status.setLanguage(c.getString(c.getColumnIndex(Sqlite.COL_LANGUAGE))); - //Close the cursor - c.close(); - //Cached status is returned - return status; - } - - /*** - * Method to hydrate cached statuses from database - * @param c Cursor - * @return List - */ - private List cursorToListStatuses(Cursor c){ - //No element found - if (c.getCount() == 0) - return null; - List statuses = new ArrayList<>(); - while (c.moveToNext() ) { - //Restore cached status - Status status = new Status(); - status.setId(c.getString(c.getColumnIndex(Sqlite.COL_STATUS_ID))); - status.setUri(c.getString(c.getColumnIndex(Sqlite.COL_URI))); - status.setUrl(c.getString(c.getColumnIndex(Sqlite.COL_URL))); - status.setAccount(Helper.restoreAccountFromString(c.getString(c.getColumnIndex(Sqlite.COL_ACCOUNT)))); - status.setCard(Helper.restoreCardFromString(c.getString(c.getColumnIndex(Sqlite.COL_CARD)))); - status.setIn_reply_to_id(c.getString(c.getColumnIndex(Sqlite.COL_IN_REPLY_TO_ID))); - status.setIn_reply_to_account_id(c.getString(c.getColumnIndex(Sqlite.COL_IN_REPLY_TO_ACCOUNT_ID))); - status.setReblog(Helper.restoreStatusFromString(c.getString(c.getColumnIndex(Sqlite.COL_REBLOG)))); - status.setContent(c.getString(c.getColumnIndex(Sqlite.COL_CONTENT))); - status.setCreated_at(Helper.stringToDate(context, c.getString(c.getColumnIndex(Sqlite.COL_CREATED_AT)))); - status.setEmojis(Helper.restoreEmojisFromString(c.getString(c.getColumnIndex(Sqlite.COL_EMOJIS)))); - status.setReblogs_count(c.getInt(c.getColumnIndex(Sqlite.COL_REBLOGS_COUNT))); - status.setFavourites_count(c.getInt(c.getColumnIndex(Sqlite.COL_FAVOURITES_COUNT))); - status.setReblogged(c.getInt(c.getColumnIndex(Sqlite.COL_REBLOGGED))==1); - status.setFavourited(c.getInt(c.getColumnIndex(Sqlite.COL_FAVOURITED))==1); - status.setMuted(c.getInt(c.getColumnIndex(Sqlite.COL_MUTED))==1); - status.setSensitive(c.getInt(c.getColumnIndex(Sqlite.COL_SENSITIVE))==1); - status.setPinned(c.getInt(c.getColumnIndex(Sqlite.COL_PINNED))==1); - status.setSpoiler_text(c.getString(c.getColumnIndex(Sqlite.COL_SPOILER_TEXT))); - status.setVisibility(c.getString(c.getColumnIndex(Sqlite.COL_VISIBILITY))); - status.setMedia_attachments(Helper.restoreAttachmentFromString(c.getString(c.getColumnIndex(Sqlite.COL_MEDIA_ATTACHMENTS)))); - status.setMentions(Helper.restoreMentionFromString(c.getString(c.getColumnIndex(Sqlite.COL_MENTIONS)))); - status.setTags(Helper.restoreTagFromString(c.getString(c.getColumnIndex(Sqlite.COL_TAGS)))); - status.setApplication(Helper.restoreApplicationFromString(c.getString(c.getColumnIndex(Sqlite.COL_APPLICATION)))); - status.setLanguage(c.getString(c.getColumnIndex(Sqlite.COL_LANGUAGE))); - statuses.add(status); - } - //Close the cursor - c.close(); - //Statuses list is returned - return statuses; - } -}