Fix account data migration for real

This commit is contained in:
Grishka 2024-10-01 23:19:48 +03:00
parent cb0d7e73d4
commit 77b6344032
6 changed files with 65 additions and 35 deletions

View File

@ -13,7 +13,7 @@ android {
applicationId "org.joinmastodon.android"
minSdk 23
targetSdk 34
versionCode 117
versionCode 118
versionName "2.7.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -35,7 +35,7 @@
*;
}
-keepnames public class org.joinmastodon.android.api.session**{
-keepnames public class org.joinmastodon.android.api.session.**{
*;
}

View File

@ -1,7 +1,11 @@
package org.joinmastodon.android.api.session;
import com.google.gson.annotations.SerializedName;
public class AccountActivationInfo{
@SerializedName(value="email", alternate="a")
public String email;
@SerializedName(value="last_email_confirmation_resend", alternate="b")
public long lastEmailConfirmationResend;
public AccountActivationInfo(String email, long lastEmailConfirmationResend){

View File

@ -9,6 +9,7 @@ import android.util.Log;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
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.FilterContext;
import org.joinmastodon.android.model.FilterResult;
import org.joinmastodon.android.model.FollowList;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.LegacyFilter;
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_NEED_UPDATE_PUSH_SETTINGS=1 << 1;
@SerializedName(value="token", alternate="a")
public Token token;
@SerializedName(value="self", alternate="b")
public Account self;
@SerializedName(value="domain", alternate="c")
public String domain;
@SerializedName(value="app", alternate="d")
public Application app;
@SerializedName(value="info_last_updated", alternate="e")
public long infoLastUpdated;
@SerializedName(value="activated", alternate="f")
public boolean activated=true;
@SerializedName(value="push_private_key", alternate="g")
public String pushPrivateKey;
@SerializedName(value="push_public_key", alternate="h")
public String pushPublicKey;
@SerializedName(value="push_auth_key", alternate="i")
public String pushAuthKey;
@SerializedName(value="push_subscription", alternate="j")
public PushSubscription pushSubscription;
@SerializedName(value="need_update_push_settings", alternate="k")
public boolean needUpdatePushSettings;
@SerializedName(value="filters_last_updated", alternate="l")
public long filtersLastUpdated;
@SerializedName(value="word_filters", alternate="m")
public List<LegacyFilter> wordFilters=new ArrayList<>();
@SerializedName(value="push_account_i_d", alternate="n")
public String pushAccountID;
@SerializedName(value="activation_info", alternate="o")
public AccountActivationInfo activationInfo;
@SerializedName(value="preferences", alternate="p")
public Preferences preferences;
private transient MastodonAPIController apiController;
private transient StatusInteractionController statusInteractionController;

View File

@ -19,6 +19,7 @@ import android.net.Uri;
import android.os.Build;
import android.util.Log;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@ -649,6 +650,7 @@ public class AccountSessionManager{
`last_updated` bigint,
`version` integer NOT NULL DEFAULT 1
)""");
maybeMigrateAccounts(db);
}
@Override
@ -662,37 +664,7 @@ public class AccountSessionManager{
`emojis` text,
`last_updated` bigint
)""");
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();
}
}
maybeMigrateAccounts(db);
}
if(oldVersion<3){
db.execSQL("ALTER TABLE `instances` ADD `version` integer NOT NULL DEFAULT 1");
@ -717,5 +689,39 @@ public class AccountSessionManager{
`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();
}
}
}
}
}

View File

@ -30,6 +30,7 @@ import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent;
import org.joinmastodon.android.fragments.discover.DiscoverFragment;
import org.joinmastodon.android.fragments.onboarding.OnboardingFollowSuggestionsFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.NotificationType;
import org.joinmastodon.android.ui.OutlineProviders;
@ -291,7 +292,10 @@ public class HomeFragment extends AppKitFragment{
}
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()
.setCallback(new Callback<>(){
@Override