From b27d77b937ab78ada06e6715b67e769cf31b51a1 Mon Sep 17 00:00:00 2001 From: nuclearfog Date: Wed, 12 Jan 2022 21:48:16 +0100 Subject: [PATCH] added blocklist updater,bug fix, removed old proguard entries --- app/proguard-rules.pro | 7 --- .../twidda/activities/AppSettings.java | 3 +- .../twidda/adapter/TweetAdapter.java | 9 ++++ .../twidda/backend/UserExcludeLoader.java | 10 ++-- .../twidda/backend/api/TweetV1.java | 21 +++++--- .../twidda/backend/api/Twitter.java | 52 ++++++++++++++++--- .../twidda/database/AccountDatabase.java | 2 +- .../{AccountDB.java => AccountImpl.java} | 6 +-- .../twidda/database/AppDatabase.java | 8 +-- ...tMessageDB.java => DirectMessageImpl.java} | 8 +-- .../twidda/database/GlobalSettings.java | 2 +- .../{LocationDB.java => LocationImpl.java} | 4 +- .../database/{TrendDB.java => TrendImpl.java} | 4 +- .../database/{TweetDB.java => TweetImpl.java} | 6 +-- .../database/{UserDB.java => UserImpl.java} | 6 +-- .../twidda/fragments/TweetFragment.java | 3 ++ .../org/nuclearfog/twidda/model/Account.java | 1 + 17 files changed, 105 insertions(+), 47 deletions(-) rename app/src/main/java/org/nuclearfog/twidda/database/{AccountDB.java => AccountImpl.java} (89%) rename app/src/main/java/org/nuclearfog/twidda/database/{DirectMessageDB.java => DirectMessageImpl.java} (78%) rename app/src/main/java/org/nuclearfog/twidda/database/{LocationDB.java => LocationImpl.java} (84%) rename app/src/main/java/org/nuclearfog/twidda/database/{TrendDB.java => TrendImpl.java} (91%) rename app/src/main/java/org/nuclearfog/twidda/database/{TweetDB.java => TweetImpl.java} (97%) rename app/src/main/java/org/nuclearfog/twidda/database/{UserDB.java => UserImpl.java} (96%) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 90baf82f..31b7bad8 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -4,13 +4,6 @@ -packageobfuscationdictionary dict/package-dictionary.txt # keep these libraries but allow obfuscating --dontwarn twitter4j.** --keep,allowobfuscation,allowoptimization class twitter4j.** {*;} --adaptclassstrings twitter4j.** - --dontwarn javax.management.DynamicMBean --keep,allowobfuscation class javax.management.DynamicMBean {*;} --adaptclassstrings javax.management.DynamicMBean -dontwarn org.conscrypt.Conscrypt -keep,allowobfuscation class org.conscrypt.Conscrypt {*;} diff --git a/app/src/main/java/org/nuclearfog/twidda/activities/AppSettings.java b/app/src/main/java/org/nuclearfog/twidda/activities/AppSettings.java index 836792bf..c2e791d1 100644 --- a/app/src/main/java/org/nuclearfog/twidda/activities/AppSettings.java +++ b/app/src/main/java/org/nuclearfog/twidda/activities/AppSettings.java @@ -268,7 +268,8 @@ public class AppSettings extends AppCompatActivity implements OnClickListener, O @Override public void onBackPressed() { - if (saveConnectionSettings()) { // fixme + if (saveConnectionSettings()) { + // todo reset proxy settings //TwitterEngine.resetTwitter(); super.onBackPressed(); } else { diff --git a/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java b/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java index 668b1d97..046501b1 100644 --- a/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/adapter/TweetAdapter.java @@ -164,6 +164,15 @@ public class TweetAdapter extends Adapter { } } + /** + * removes all items from adapter + */ + @MainThread + public void clear() { + tweets.clear(); + notifyDataSetChanged(); + } + /** * check if list is empty * diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/UserExcludeLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/UserExcludeLoader.java index 2efa6f5d..462b65ef 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/UserExcludeLoader.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/UserExcludeLoader.java @@ -12,10 +12,12 @@ import org.nuclearfog.twidda.database.ExcludeDatabase; import org.nuclearfog.twidda.model.User; import java.lang.ref.WeakReference; +import java.util.List; /** * Backend of {@link UserExclude} - * performs user mute or block actions and exports block list to database + * performs user mute or block actions and stores a list of IDs with blocked/muted users + * This list is used to filter search results * * @author nuclearfog */ @@ -49,9 +51,9 @@ public class UserExcludeLoader extends AsyncTask { @Override protected Void doInBackground(String[] names) { try { - if (mode == Mode.REFRESH) { // fixme - //List ids = mTwitter.getExcludedUserIDs(); - //excludeDatabase.setExcludeList(ids); + if (mode == Mode.REFRESH) { + List ids = twitter.getIdBlocklist(); + excludeDatabase.setExcludeList(ids); } else if (mode == Mode.MUTE_USER) { User user = twitter.muteUser(names[0]); appDatabase.storeUser(user); diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java index 14e2b4aa..d4c3df53 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/TweetV1.java @@ -68,23 +68,32 @@ class TweetV1 implements Tweet { isSensitive = json.optBoolean("possibly_sensitive"); timestamp = StringTools.getTime(json.optString("created_at")); source = StringTools.getSource(json.optString("source")); - String location = json.optString("place"); String replyName = json.optString("in_reply_to_screen_name"); + JSONObject locationJson = json.optJSONObject("place"); + JSONObject coordinateJson = json.optJSONObject("coordinates"); JSONObject user = json.getJSONObject("user"); JSONObject quoted_tweet = json.optJSONObject("retweeted_status"); JSONObject user_retweet = json.optJSONObject("current_user_retweet"); JSONObject entities = json.optJSONObject("entities"); JSONObject extEntities = json.optJSONObject("extended_entities"); - JSONObject geo = json.optJSONObject("geo"); author = new UserV1(user, twitterId); - if (!location.equals("null")) - this.location = location; + if (locationJson != null) { + location = locationJson.optString("full_name"); + } + if (coordinateJson != null) { + if (coordinateJson.optString("type").equals("Point")) { + JSONArray coordinateArray = coordinateJson.optJSONArray("coordinates"); + if (coordinateArray != null && coordinateArray.length() == 2) { + double lon = coordinateArray.getDouble(0); + double lat = coordinateArray.getDouble(1); + coordinates = lon + "," + lat; + } + } + } if (!replyName.equals("null")) this.replyName = '@' + replyName; - if (geo != null) - coordinates = geo.optString("coordinates"); if (user_retweet != null) retweetId = user_retweet.optLong("id"); if (quoted_tweet != null) diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java index bef6d27a..f325b3ff 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/Twitter.java @@ -30,7 +30,6 @@ import org.nuclearfog.twidda.model.UserList; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.net.Proxy; import java.net.URL; import java.security.KeyStore; import java.util.ArrayList; @@ -75,6 +74,7 @@ public class Twitter { private static final String USER_LIST_MEMBER = API + "1.1/lists/members.json"; private static final String USER_LIST_SUBSCRIBER = API + "1.1/lists/subscribers.json"; private static final String BLOCK_LIST = API + "1.1/blocks/list.json"; + private static final String BLOCK_ID_LIST = API + "1.1/blocks/ids.json"; private static final String MUTES_LIST = API + "1.1/mutes/users/list.json"; private static final String SHOW_TWEET = API + "1.1/statuses/show.json"; private static final String SHOW_HOME = API + "1.1/statuses/home_timeline.json"; @@ -389,7 +389,9 @@ public class Twitter { public User blockUser(long userId) throws TwitterException { List params = new ArrayList<>(4); params.add("user_id=" + userId); - return getUser1(USER_BLOCK, params); // todo add to exclude list + User user = getUser1(USER_BLOCK, params); + filterList.addUser(userId); + return user; } /** @@ -403,7 +405,9 @@ public class Twitter { if (screen_name.startsWith("@")) screen_name = screen_name.substring(1); params.add("screen_name=" + screen_name); - return getUser1(USER_BLOCK, params); + User user = getUser1(USER_BLOCK, params); + filterList.addUser(user.getId()); + return user; } /** @@ -845,9 +849,9 @@ public class Twitter { String idStr = buf.substring(0, buf.lastIndexOf("%2C")); params.add("media_ids=" + idStr); } - if (coordinates != null) { // fixme not working with coordinates - String lat = Double.toString(coordinates[0]); - String lon = Double.toString(coordinates[1]); + if (coordinates != null) { + String lon = Double.toString(coordinates[0]); + String lat = Double.toString(coordinates[1]); params.add("lat=" + StringTools.encode(lat)); params.add("long=" + StringTools.encode(lon)); } @@ -1236,6 +1240,42 @@ public class Twitter { updateImage(PROFILE_UPDATE_BANNER, path, "banner"); } + /** + * returns a list of blocked user IDs + * + * @return list of IDs + */ + public List getIdBlocklist() throws TwitterException { + try { + long cursor = -1; + List result = new ArrayList<>(100); + // the API returns up to 5000 blocked user IDs + // but for bigger lists, we have to parse the whole list + for (int i = 0 ; i < 10 && cursor != 0 ; i++) { + List params = new ArrayList<>(2); + params.add("cursor=" + cursor); + Response response = get(BLOCK_ID_LIST, params); + if (response.body() != null) { + JSONObject json = new JSONObject(response.body().string()); + if (response.code() == 200) { + JSONArray idArray = json.getJSONArray("ids"); + cursor = json.optLong("next_cursor"); + for (int pos = 0; pos < idArray.length(); pos++) { + result.add(idArray.getLong(pos)); + } + } else { + throw new TwitterException(json); + } + } + } + return result; + } catch (IOException err) { + throw new TwitterException(err); + } catch (JSONException err) { + throw new TwitterException(err); + } + } + /** * get tweets using an endpoint * diff --git a/app/src/main/java/org/nuclearfog/twidda/database/AccountDatabase.java b/app/src/main/java/org/nuclearfog/twidda/database/AccountDatabase.java index dc02db2f..aff664e8 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/AccountDatabase.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/AccountDatabase.java @@ -92,7 +92,7 @@ public class AccountDatabase { String key1 = cursor.getString(1); String key2 = cursor.getString(2); long date = cursor.getLong(3); - AccountDB account = new AccountDB(id, date, key1, key2); + AccountImpl account = new AccountImpl(id, date, key1, key2); account.addUser(database.getUser(id)); result.add(account); } while (cursor.moveToNext()); diff --git a/app/src/main/java/org/nuclearfog/twidda/database/AccountDB.java b/app/src/main/java/org/nuclearfog/twidda/database/AccountImpl.java similarity index 89% rename from app/src/main/java/org/nuclearfog/twidda/database/AccountDB.java rename to app/src/main/java/org/nuclearfog/twidda/database/AccountImpl.java index 505aabcb..da2d3b59 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/AccountDB.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/AccountImpl.java @@ -7,11 +7,11 @@ import org.nuclearfog.twidda.model.Account; import org.nuclearfog.twidda.model.User; /** - * container class for user login information + * database implementation of account * * @author nuclearfog */ -class AccountDB implements Account { +class AccountImpl implements Account { /** * id of the user @@ -31,7 +31,7 @@ class AccountDB implements Account { private User user; - AccountDB(long userId, long loginDate, String key1, String key2) { + AccountImpl(long userId, long loginDate, String key1, String key2) { this.userId = userId; this.loginDate = loginDate; this.key1 = key1; diff --git a/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java b/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java index 6c61845b..16075180 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/AppDatabase.java @@ -580,7 +580,7 @@ public class AppDatabase { List trends = new LinkedList<>(); if (cursor.moveToFirst()) { do { - trends.add(new TrendDB(cursor)); + trends.add(new TrendImpl(cursor)); } while (cursor.moveToNext()); } cursor.close(); @@ -600,7 +600,7 @@ public class AppDatabase { Cursor cursor = db.rawQuery(MESSAGE_QUERY, args); if (cursor.moveToFirst()) { do { - result.add(new DirectMessageDB(cursor, homeId)); + result.add(new DirectMessageImpl(cursor, homeId)); } while (cursor.moveToNext()); } cursor.close(); @@ -643,7 +643,7 @@ public class AppDatabase { * @return tweet instance */ private Tweet getStatus(Cursor cursor) { - TweetDB result = new TweetDB(cursor, homeId); + TweetImpl result = new TweetImpl(cursor, homeId); // check if there is an embedded tweet if (result.getEmbeddedTweetId() > 1) result.addEmbeddedTweet(getStatus(result.getEmbeddedTweetId())); @@ -664,7 +664,7 @@ public class AppDatabase { User user = null; if (cursor.moveToFirst()) - user = new UserDB(cursor, homeId); + user = new UserImpl(cursor, homeId); cursor.close(); return user; } diff --git a/app/src/main/java/org/nuclearfog/twidda/database/DirectMessageDB.java b/app/src/main/java/org/nuclearfog/twidda/database/DirectMessageImpl.java similarity index 78% rename from app/src/main/java/org/nuclearfog/twidda/database/DirectMessageDB.java rename to app/src/main/java/org/nuclearfog/twidda/database/DirectMessageImpl.java index dc9b08ef..108cb91e 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/DirectMessageDB.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/DirectMessageImpl.java @@ -6,7 +6,7 @@ import org.nuclearfog.twidda.model.DirectMessage; import org.nuclearfog.twidda.model.User; -class DirectMessageDB implements DirectMessage { +class DirectMessageImpl implements DirectMessage { private long id; private long time; @@ -16,12 +16,12 @@ class DirectMessageDB implements DirectMessage { private User receiver; - DirectMessageDB(Cursor cursor, long currentId) { + DirectMessageImpl(Cursor cursor, long currentId) { text = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseAdapter.MessageTable.MESSAGE)); time = cursor.getLong(cursor.getColumnIndexOrThrow(DatabaseAdapter.MessageTable.SINCE)); id = cursor.getLong(cursor.getColumnIndexOrThrow(DatabaseAdapter.MessageTable.ID)); - sender = new UserDB(cursor, DatabaseAdapter.UserTable.ALIAS_1 + ".", currentId); - receiver = new UserDB(cursor, DatabaseAdapter.UserTable.ALIAS_2 + ".", currentId); + sender = new UserImpl(cursor, DatabaseAdapter.UserTable.ALIAS_1 + ".", currentId); + receiver = new UserImpl(cursor, DatabaseAdapter.UserTable.ALIAS_2 + ".", currentId); } @Override diff --git a/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java b/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java index df6508ec..f5c9f7a5 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/GlobalSettings.java @@ -1024,7 +1024,7 @@ public class GlobalSettings { proxyPass = settings.getString(PROXY_PASS, ""); String place = settings.getString(TREND_LOC, DEFAULT_LOCATION_NAME); int woeId = settings.getInt(TREND_ID, DEFAULT_LOCATION_ID); - location = new LocationDB(place, woeId); + location = new LocationImpl(place, woeId); api_key1 = settings.getString(CUSTOM_CONSUMER_KEY_1, ""); api_key2 = settings.getString(CUSTOM_CONSUMER_KEY_2, ""); diff --git a/app/src/main/java/org/nuclearfog/twidda/database/LocationDB.java b/app/src/main/java/org/nuclearfog/twidda/database/LocationImpl.java similarity index 84% rename from app/src/main/java/org/nuclearfog/twidda/database/LocationDB.java rename to app/src/main/java/org/nuclearfog/twidda/database/LocationImpl.java index d6d21141..49d77357 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/LocationDB.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/LocationImpl.java @@ -2,7 +2,7 @@ package org.nuclearfog.twidda.database; import org.nuclearfog.twidda.model.Location; -class LocationDB implements Location { +class LocationImpl implements Location { private String placeName; private int worldId; @@ -13,7 +13,7 @@ class LocationDB implements Location { * @param placeName name of locale * @param worldId woe id */ - LocationDB(String placeName, int worldId) { + LocationImpl(String placeName, int worldId) { this.placeName = placeName; this.worldId = worldId; } diff --git a/app/src/main/java/org/nuclearfog/twidda/database/TrendDB.java b/app/src/main/java/org/nuclearfog/twidda/database/TrendImpl.java similarity index 91% rename from app/src/main/java/org/nuclearfog/twidda/database/TrendDB.java rename to app/src/main/java/org/nuclearfog/twidda/database/TrendImpl.java index e8f916bf..233e92e6 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/TrendDB.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/TrendImpl.java @@ -4,13 +4,13 @@ import android.database.Cursor; import org.nuclearfog.twidda.model.Trend; -class TrendDB implements Trend { +class TrendImpl implements Trend { private String name; private int range; private int rank; - TrendDB(Cursor cursor) { + TrendImpl(Cursor cursor) { name = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseAdapter.TrendTable.TREND)); range = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseAdapter.TrendTable.VOL)); rank = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseAdapter.TrendTable.INDEX)); diff --git a/app/src/main/java/org/nuclearfog/twidda/database/TweetDB.java b/app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java similarity index 97% rename from app/src/main/java/org/nuclearfog/twidda/database/TweetDB.java rename to app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java index 3bfbb0dc..d7fe1273 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/TweetDB.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/TweetImpl.java @@ -16,7 +16,7 @@ import java.util.regex.Pattern; * * @author nuclearfog */ -class TweetDB implements Tweet { +class TweetImpl implements Tweet { private static final Pattern SEPARATOR = Pattern.compile(";"); @@ -47,7 +47,7 @@ class TweetDB implements Tweet { private String source; - TweetDB(Cursor cursor, long currentUserId) { + TweetImpl(Cursor cursor, long currentUserId) { time = cursor.getLong(cursor.getColumnIndexOrThrow(DatabaseAdapter.TweetTable.SINCE)); tweet = cursor.getString(cursor.getColumnIndexOrThrow(DatabaseAdapter.TweetTable.TWEET)); retweetCount = cursor.getInt(cursor.getColumnIndexOrThrow(DatabaseAdapter.TweetTable.RETWEET)); @@ -76,7 +76,7 @@ class TweetDB implements Tweet { mediaType = MIME_VIDEO; else mediaType = MIME_NONE; - this.user = new UserDB(cursor, currentUserId); + this.user = new UserImpl(cursor, currentUserId); } @Override diff --git a/app/src/main/java/org/nuclearfog/twidda/database/UserDB.java b/app/src/main/java/org/nuclearfog/twidda/database/UserImpl.java similarity index 96% rename from app/src/main/java/org/nuclearfog/twidda/database/UserDB.java rename to app/src/main/java/org/nuclearfog/twidda/database/UserImpl.java index 910132a1..f6072423 100644 --- a/app/src/main/java/org/nuclearfog/twidda/database/UserDB.java +++ b/app/src/main/java/org/nuclearfog/twidda/database/UserImpl.java @@ -8,7 +8,7 @@ import androidx.annotation.NonNull; import org.nuclearfog.twidda.model.User; -class UserDB implements User { +class UserImpl implements User { private long userID; private long created; @@ -35,11 +35,11 @@ class UserDB implements User { private String profileImg; private String bannerImg; - UserDB(Cursor cursor, long currentUserId) { + UserImpl(Cursor cursor, long currentUserId) { this(cursor, "", currentUserId); } - UserDB(Cursor cursor, String prefix, long currentUserId) { + UserImpl(Cursor cursor, String prefix, long currentUserId) { userID = cursor.getLong(cursor.getColumnIndexOrThrow(prefix + DatabaseAdapter.UserTable.ID)); username = cursor.getString(cursor.getColumnIndexOrThrow(prefix + DatabaseAdapter.UserTable.USERNAME)); screenName = cursor.getString(cursor.getColumnIndexOrThrow(prefix + DatabaseAdapter.UserTable.SCREENNAME)); diff --git a/app/src/main/java/org/nuclearfog/twidda/fragments/TweetFragment.java b/app/src/main/java/org/nuclearfog/twidda/fragments/TweetFragment.java index 013b6fc9..174cbf93 100644 --- a/app/src/main/java/org/nuclearfog/twidda/fragments/TweetFragment.java +++ b/app/src/main/java/org/nuclearfog/twidda/fragments/TweetFragment.java @@ -143,6 +143,9 @@ public class TweetFragment extends ListFragment implements TweetClickListener { @Override protected void onReset() { + if (adapter != null) { + adapter.clear(); + } load(0, 0, CLEAR_LIST); setRefresh(true); } diff --git a/app/src/main/java/org/nuclearfog/twidda/model/Account.java b/app/src/main/java/org/nuclearfog/twidda/model/Account.java index 8352d90b..79c2a320 100644 --- a/app/src/main/java/org/nuclearfog/twidda/model/Account.java +++ b/app/src/main/java/org/nuclearfog/twidda/model/Account.java @@ -4,6 +4,7 @@ import androidx.annotation.Nullable; /** * interface of account implementations + * An account class collects information about a saved login. * * @author nuclearfog */