Fix account data migration for real
This commit is contained in:
@@ -13,7 +13,7 @@ android {
|
|||||||
applicationId "org.joinmastodon.android"
|
applicationId "org.joinmastodon.android"
|
||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 34
|
targetSdk 34
|
||||||
versionCode 117
|
versionCode 118
|
||||||
versionName "2.7.0"
|
versionName "2.7.0"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|||||||
2
mastodon/proguard-rules.pro
vendored
2
mastodon/proguard-rules.pro
vendored
@@ -35,7 +35,7 @@
|
|||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
|
||||||
-keepnames public class org.joinmastodon.android.api.session**{
|
-keepnames public class org.joinmastodon.android.api.session.**{
|
||||||
*;
|
*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package org.joinmastodon.android.api.session;
|
package org.joinmastodon.android.api.session;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
public class AccountActivationInfo{
|
public class AccountActivationInfo{
|
||||||
|
@SerializedName(value="email", alternate="a")
|
||||||
public String email;
|
public String email;
|
||||||
|
@SerializedName(value="last_email_confirmation_resend", alternate="b")
|
||||||
public long lastEmailConfirmationResend;
|
public long lastEmailConfirmationResend;
|
||||||
|
|
||||||
public AccountActivationInfo(String email, long lastEmailConfirmationResend){
|
public AccountActivationInfo(String email, long lastEmailConfirmationResend){
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
import org.joinmastodon.android.E;
|
import org.joinmastodon.android.E;
|
||||||
@@ -30,7 +31,6 @@ import org.joinmastodon.android.model.Application;
|
|||||||
import org.joinmastodon.android.model.FilterAction;
|
import org.joinmastodon.android.model.FilterAction;
|
||||||
import org.joinmastodon.android.model.FilterContext;
|
import org.joinmastodon.android.model.FilterContext;
|
||||||
import org.joinmastodon.android.model.FilterResult;
|
import org.joinmastodon.android.model.FilterResult;
|
||||||
import org.joinmastodon.android.model.FollowList;
|
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
import org.joinmastodon.android.model.LegacyFilter;
|
import org.joinmastodon.android.model.LegacyFilter;
|
||||||
import org.joinmastodon.android.model.Preferences;
|
import org.joinmastodon.android.model.Preferences;
|
||||||
@@ -57,21 +57,37 @@ public class AccountSession{
|
|||||||
public static final int FLAG_ACTIVATED=1;
|
public static final int FLAG_ACTIVATED=1;
|
||||||
public static final int FLAG_NEED_UPDATE_PUSH_SETTINGS=1 << 1;
|
public static final int FLAG_NEED_UPDATE_PUSH_SETTINGS=1 << 1;
|
||||||
|
|
||||||
|
@SerializedName(value="token", alternate="a")
|
||||||
public Token token;
|
public Token token;
|
||||||
|
@SerializedName(value="self", alternate="b")
|
||||||
public Account self;
|
public Account self;
|
||||||
|
@SerializedName(value="domain", alternate="c")
|
||||||
public String domain;
|
public String domain;
|
||||||
|
@SerializedName(value="app", alternate="d")
|
||||||
public Application app;
|
public Application app;
|
||||||
|
@SerializedName(value="info_last_updated", alternate="e")
|
||||||
public long infoLastUpdated;
|
public long infoLastUpdated;
|
||||||
|
@SerializedName(value="activated", alternate="f")
|
||||||
public boolean activated=true;
|
public boolean activated=true;
|
||||||
|
@SerializedName(value="push_private_key", alternate="g")
|
||||||
public String pushPrivateKey;
|
public String pushPrivateKey;
|
||||||
|
@SerializedName(value="push_public_key", alternate="h")
|
||||||
public String pushPublicKey;
|
public String pushPublicKey;
|
||||||
|
@SerializedName(value="push_auth_key", alternate="i")
|
||||||
public String pushAuthKey;
|
public String pushAuthKey;
|
||||||
|
@SerializedName(value="push_subscription", alternate="j")
|
||||||
public PushSubscription pushSubscription;
|
public PushSubscription pushSubscription;
|
||||||
|
@SerializedName(value="need_update_push_settings", alternate="k")
|
||||||
public boolean needUpdatePushSettings;
|
public boolean needUpdatePushSettings;
|
||||||
|
@SerializedName(value="filters_last_updated", alternate="l")
|
||||||
public long filtersLastUpdated;
|
public long filtersLastUpdated;
|
||||||
|
@SerializedName(value="word_filters", alternate="m")
|
||||||
public List<LegacyFilter> wordFilters=new ArrayList<>();
|
public List<LegacyFilter> wordFilters=new ArrayList<>();
|
||||||
|
@SerializedName(value="push_account_i_d", alternate="n")
|
||||||
public String pushAccountID;
|
public String pushAccountID;
|
||||||
|
@SerializedName(value="activation_info", alternate="o")
|
||||||
public AccountActivationInfo activationInfo;
|
public AccountActivationInfo activationInfo;
|
||||||
|
@SerializedName(value="preferences", alternate="p")
|
||||||
public Preferences preferences;
|
public Preferences preferences;
|
||||||
private transient MastodonAPIController apiController;
|
private transient MastodonAPIController apiController;
|
||||||
private transient StatusInteractionController statusInteractionController;
|
private transient StatusInteractionController statusInteractionController;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import android.net.Uri;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
@@ -649,6 +650,7 @@ public class AccountSessionManager{
|
|||||||
`last_updated` bigint,
|
`last_updated` bigint,
|
||||||
`version` integer NOT NULL DEFAULT 1
|
`version` integer NOT NULL DEFAULT 1
|
||||||
)""");
|
)""");
|
||||||
|
maybeMigrateAccounts(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -662,37 +664,7 @@ public class AccountSessionManager{
|
|||||||
`emojis` text,
|
`emojis` text,
|
||||||
`last_updated` bigint
|
`last_updated` bigint
|
||||||
)""");
|
)""");
|
||||||
|
maybeMigrateAccounts(db);
|
||||||
File accountsFile=new File(MastodonApp.context.getFilesDir(), "accounts.json");
|
|
||||||
if(accountsFile.exists()){
|
|
||||||
HashSet<String> domains=new HashSet<>();
|
|
||||||
try(FileInputStream in=new FileInputStream(accountsFile)){
|
|
||||||
JsonObject jobj=JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)).getAsJsonObject();
|
|
||||||
ContentValues values=new ContentValues();
|
|
||||||
for(JsonElement jacc:jobj.getAsJsonArray("accounts")){
|
|
||||||
AccountSession session=MastodonAPIController.gson.fromJson(jacc, AccountSession.class);
|
|
||||||
domains.add(session.domain.toLowerCase());
|
|
||||||
session.toContentValues(values);
|
|
||||||
db.insertWithOnConflict("accounts", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
|
||||||
}
|
|
||||||
}catch(Exception x){
|
|
||||||
Log.e(TAG, "Error migrating accounts", x);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
accountsFile.delete();
|
|
||||||
for(String domain:domains){
|
|
||||||
File file=new File(MastodonApp.context.getFilesDir(), "instance_"+domain.replace('.', '_')+".json");
|
|
||||||
try(FileInputStream in=new FileInputStream(file)){
|
|
||||||
JsonObject jobj=JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)).getAsJsonObject();
|
|
||||||
|
|
||||||
insertInstanceIntoDatabase(db, domain, MastodonAPIController.gson.fromJson(jobj.get("instance"), Instance.class),
|
|
||||||
MastodonAPIController.gson.fromJson(jobj.get("emojis"), new TypeToken<>(){}.getType()), jobj.get("last_updated").getAsLong());
|
|
||||||
}catch(Exception x){
|
|
||||||
Log.w(TAG, "Error reading instance info file for "+domain, x);
|
|
||||||
}
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(oldVersion<3){
|
if(oldVersion<3){
|
||||||
db.execSQL("ALTER TABLE `instances` ADD `version` integer NOT NULL DEFAULT 1");
|
db.execSQL("ALTER TABLE `instances` ADD `version` integer NOT NULL DEFAULT 1");
|
||||||
@@ -717,5 +689,39 @@ public class AccountSessionManager{
|
|||||||
`preferences` text
|
`preferences` text
|
||||||
)""");
|
)""");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maybeMigrateAccounts(SQLiteDatabase db){
|
||||||
|
File accountsFile=new File(MastodonApp.context.getFilesDir(), "accounts.json");
|
||||||
|
if(accountsFile.exists()){
|
||||||
|
HashSet<String> domains=new HashSet<>();
|
||||||
|
try(FileInputStream in=new FileInputStream(accountsFile)){
|
||||||
|
JsonObject jobj=JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)).getAsJsonObject();
|
||||||
|
ContentValues values=new ContentValues();
|
||||||
|
JsonArray accounts=jobj.has("a") ? jobj.getAsJsonArray("a") : jobj.getAsJsonArray("accounts");
|
||||||
|
for(JsonElement jacc:accounts){
|
||||||
|
AccountSession session=MastodonAPIController.gson.fromJson(jacc, AccountSession.class);
|
||||||
|
domains.add(session.domain.toLowerCase());
|
||||||
|
session.toContentValues(values);
|
||||||
|
db.insertWithOnConflict("accounts", null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||||
|
}
|
||||||
|
}catch(Exception x){
|
||||||
|
Log.e(TAG, "Error migrating accounts", x);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
accountsFile.delete();
|
||||||
|
for(String domain:domains){
|
||||||
|
File file=new File(MastodonApp.context.getFilesDir(), "instance_"+domain.replace('.', '_')+".json");
|
||||||
|
try(FileInputStream in=new FileInputStream(file)){
|
||||||
|
JsonObject jobj=JsonParser.parseReader(new InputStreamReader(in, StandardCharsets.UTF_8)).getAsJsonObject();
|
||||||
|
|
||||||
|
insertInstanceIntoDatabase(db, domain, MastodonAPIController.gson.fromJson(jobj.get("instance"), Instance.class),
|
||||||
|
MastodonAPIController.gson.fromJson(jobj.get("emojis"), new TypeToken<>(){}.getType()), jobj.get("last_updated").getAsLong());
|
||||||
|
}catch(Exception x){
|
||||||
|
Log.w(TAG, "Error reading instance info file for "+domain, x);
|
||||||
|
}
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent;
|
|||||||
import org.joinmastodon.android.fragments.discover.DiscoverFragment;
|
import org.joinmastodon.android.fragments.discover.DiscoverFragment;
|
||||||
import org.joinmastodon.android.fragments.onboarding.OnboardingFollowSuggestionsFragment;
|
import org.joinmastodon.android.fragments.onboarding.OnboardingFollowSuggestionsFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
import org.joinmastodon.android.model.Notification;
|
import org.joinmastodon.android.model.Notification;
|
||||||
import org.joinmastodon.android.model.NotificationType;
|
import org.joinmastodon.android.model.NotificationType;
|
||||||
import org.joinmastodon.android.ui.OutlineProviders;
|
import org.joinmastodon.android.ui.OutlineProviders;
|
||||||
@@ -291,7 +292,10 @@ public class HomeFragment extends AppKitFragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void reloadNotificationsForUnreadCount(){
|
private void reloadNotificationsForUnreadCount(){
|
||||||
if(AccountSessionManager.get(accountID).getInstanceInfo().getApiVersion()>=2){
|
Instance instance=AccountSessionManager.get(accountID).getInstanceInfo();
|
||||||
|
if(instance==null)
|
||||||
|
return;
|
||||||
|
if(instance.getApiVersion()>=2){
|
||||||
new GetUnreadNotificationsCount()
|
new GetUnreadNotificationsCount()
|
||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user