Implement logic

This commit is contained in:
Thomas 2020-12-30 15:37:09 +01:00
parent 439decf6a9
commit bbfa278d6b
8 changed files with 417 additions and 53 deletions

View File

@ -50,6 +50,7 @@ android {
buildConfigField "boolean", "surfing_mode", "false"
buildConfigField "boolean", "sepia_search", "false"
buildConfigField "boolean", "instance_switcher", "true"
buildConfigField "boolean", "allow_remote_connections", "false"
}
google_peertube_apps_educ {
applicationId "app.fedilab.fedilabtube"
@ -61,6 +62,7 @@ android {
buildConfigField "boolean", "surfing_mode", "false"
buildConfigField "boolean", "sepia_search", "false"
buildConfigField "boolean", "instance_switcher", "true"
buildConfigField "boolean", "allow_remote_connections", "false"
}
fdroid_full {
applicationId "app.fedilab.tubelab"
@ -72,6 +74,7 @@ android {
buildConfigField "boolean", "surfing_mode", "true"
buildConfigField "boolean", "sepia_search", "true"
buildConfigField "boolean", "instance_switcher", "true"
buildConfigField "boolean", "allow_remote_connections", "true"
}
google_full {
applicationId "app.fedilab.tubelab"
@ -83,6 +86,7 @@ android {
buildConfigField "boolean", "surfing_mode", "true"
buildConfigField "boolean", "sepia_search", "true"
buildConfigField "boolean", "instance_switcher", "true"
buildConfigField "boolean", "allow_remote_connections", "true"
}
queermotion {
applicationId "org.queermotion.peertube"
@ -94,6 +98,7 @@ android {
buildConfigField "boolean", "surfing_mode", "false"
buildConfigField "boolean", "sepia_search", "false"
buildConfigField "boolean", "instance_switcher", "false"
buildConfigField "boolean", "allow_remote_connections", "false"
}
bittube {
applicationId "app.fedilab.bittube"
@ -105,7 +110,7 @@ android {
buildConfigField "boolean", "surfing_mode", "false"
buildConfigField "boolean", "sepia_search", "false"
buildConfigField "boolean", "instance_switcher", "true"
buildConfigField "boolean", "allow_remote_connections", "false"
}
}

View File

@ -41,11 +41,13 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import app.fedilab.fedilabtube.client.RetrofitMastodonAPI;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Oauth;
import app.fedilab.fedilabtube.client.entities.OauthParams;
import app.fedilab.fedilabtube.client.entities.Token;
import app.fedilab.fedilabtube.client.entities.WellKnownNodeinfo;
import app.fedilab.fedilabtube.databinding.ActivityLoginBinding;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.helper.HelperAcadInstance;
@ -76,6 +78,7 @@ public class LoginActivity extends AppCompatActivity {
SpannableString content_create;
//noinspection ConstantConditions
if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
content_create = new SpannableString(getString(R.string.register_account));
} else {
@ -98,6 +101,7 @@ public class LoginActivity extends AppCompatActivity {
if (BuildConfig.full_instances && BuildConfig.instance_switcher) {
binding.loginInstanceContainer.setVisibility(View.VISIBLE);
}
//noinspection ConstantConditions
if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
binding.loginInstance.setText("queermotion.org");
}
@ -211,7 +215,7 @@ public class LoginActivity extends AppCompatActivity {
return;
}
binding.loginButton.setEnabled(false);
String instance, host;
String instance;
if (!BuildConfig.full_instances) {
String[] emailArray = binding.loginUid.getText().toString().split("@");
if (emailArray.length > 1 && !Arrays.asList(HelperAcadInstance.valideEmails).contains(emailArray[1])) {
@ -221,21 +225,19 @@ public class LoginActivity extends AppCompatActivity {
}
instance = HelperInstance.getLiveInstance(LoginActivity.this);
host = instance;
} else {
if (binding.loginInstance.getText() == null || binding.loginInstance.getText().toString().trim().length() == 0) {
Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show();
binding.loginButton.setEnabled(true);
return;
}
instance = host = binding.loginInstance.getText().toString().trim().toLowerCase();
instance = binding.loginInstance.getText().toString().trim().toLowerCase();
}
if (instance.startsWith("http")) {
try {
URL url = new URL(instance);
instance = url.getHost();
host = instance;
} catch (MalformedURLException e) {
e.printStackTrace();
}
@ -243,7 +245,6 @@ public class LoginActivity extends AppCompatActivity {
try {
URL url = new URL("https://" + instance);
instance = url.getHost();
host = instance;
} catch (MalformedURLException e) {
e.printStackTrace();
}
@ -254,57 +255,133 @@ public class LoginActivity extends AppCompatActivity {
return;
}
String finalInstance = instance;
String finalHost = host;
if (BuildConfig.full_instances) {
new Thread(() -> {
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE);
if (oauth == null) {
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
});
return;
}
client_id = oauth.getClient_id();
client_secret = oauth.getClient_secret();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
editor.putString(Helper.CLIENT_SECRET, client_secret);
editor.apply();
OauthParams oauthParams = new OauthParams();
oauthParams.setClient_id(client_id);
oauthParams.setClient_secret(client_secret);
oauthParams.setGrant_type("password");
oauthParams.setScope("user");
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
if (binding.loginPasswd.getText() != null) {
oauthParams.setPassword(binding.loginPasswd.getText().toString());
}
try {
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalHost);
} catch (final Exception | Error e) {
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
try {
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalHost);
} catch (Error error) {
Error.displayError(LoginActivity.this, error);
error.printStackTrace();
runOnUiThread(() -> binding.loginButton.setEnabled(true));
boolean connectAPeertubeAccount = true;
WellKnownNodeinfo.NodeInfo instanceNodeInfo = null;
if (BuildConfig.allow_remote_connections) {
instanceNodeInfo = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).getNodeInfo();
if (instanceNodeInfo != null && instanceNodeInfo.getSoftware().getName().toUpperCase().trim().compareTo("PEERTUBE") != 0) {
connectAPeertubeAccount = false;
}
}
if (connectAPeertubeAccount) {
connectToPeertube(finalInstance);
} else {
connectToFediverse(finalInstance, instanceNodeInfo);
}
}).start();
}
}
});
}
private void connectToFediverse(String finalInstance, WellKnownNodeinfo.NodeInfo instanceNodeInfo) {
switch (instanceNodeInfo.getSoftware().getName().toUpperCase().trim()) {
case "MASTODON":
case "PLEROMA":
Oauth oauth = new RetrofitMastodonAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.REDIRECT_CONTENT, Helper.OAUTH_SCOPES_MASTODON, Helper.WEBSITE_VALUE);
if (oauth == null) {
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
});
return;
}
client_id = oauth.getClient_id();
client_secret = oauth.getClient_secret();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
editor.putString(Helper.CLIENT_SECRET, client_secret);
editor.apply();
OauthParams oauthParams = new OauthParams();
oauthParams.setClient_id(client_id);
oauthParams.setClient_secret(client_secret);
oauthParams.setGrant_type("password");
oauthParams.setScope("user");
if (binding.loginUid.getText() != null) {
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
}
if (binding.loginPasswd.getText() != null) {
oauthParams.setPassword(binding.loginPasswd.getText().toString());
}
try {
Token token = new RetrofitMastodonAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalInstance, instanceNodeInfo.getSoftware().getName().toUpperCase().trim());
} catch (final Exception | Error e) {
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
try {
Token token = new RetrofitMastodonAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalInstance, instanceNodeInfo.getSoftware().getName().toUpperCase().trim());
} catch (Error error) {
Error.displayError(LoginActivity.this, error);
error.printStackTrace();
runOnUiThread(() -> binding.loginButton.setEnabled(true));
}
}
break;
case "FRIENDICA":
break;
}
}
/**
* Oauth process for Peertube
*
* @param finalInstance String
*/
private void connectToPeertube(String finalInstance) {
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE);
if (oauth == null) {
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
});
return;
}
client_id = oauth.getClient_id();
client_secret = oauth.getClient_secret();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
editor.putString(Helper.CLIENT_SECRET, client_secret);
editor.apply();
OauthParams oauthParams = new OauthParams();
oauthParams.setClient_id(client_id);
oauthParams.setClient_secret(client_secret);
oauthParams.setGrant_type("password");
oauthParams.setScope("user");
if (binding.loginUid.getText() != null) {
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
}
if (binding.loginPasswd.getText() != null) {
oauthParams.setPassword(binding.loginPasswd.getText().toString());
}
try {
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalInstance, null);
} catch (final Exception | Error e) {
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
try {
Token token = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).manageToken(oauthParams);
proceedLogin(token, finalInstance, null);
} catch (Error error) {
Error.displayError(LoginActivity.this, error);
error.printStackTrace();
runOnUiThread(() -> binding.loginButton.setEnabled(true));
}
}
}
@SuppressLint("ApplySharedPref")
private void proceedLogin(Token token, String host) {
private void proceedLogin(Token token, String host, String software) {
runOnUiThread(() -> {
if (token != null) {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
@ -313,7 +390,7 @@ public class LoginActivity extends AppCompatActivity {
editor.putString(Helper.PREF_INSTANCE, host);
editor.commit();
//Update the account with the token;
updateCredential(LoginActivity.this, token.getAccess_token(), client_id, client_secret, token.getRefresh_token(), host);
updateCredential(LoginActivity.this, token.getAccess_token(), client_id, client_secret, token.getRefresh_token(), host, software);
} else {
binding.loginButton.setEnabled(true);
}

View File

@ -0,0 +1,47 @@
package app.fedilab.fedilabtube.client;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of TubeLab
*
* 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.
*
* TubeLab 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 TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
import app.fedilab.fedilabtube.client.data.AccountData;
import app.fedilab.fedilabtube.client.entities.Oauth;
import app.fedilab.fedilabtube.client.entities.Token;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.Query;
interface MastodonService {
@GET("apps")
Call<Oauth> getOauth(@Query("client_name") String client_name, @Query("redirect_uris") String redirect_uris, @Query("scopes") String scopes, @Query("website") String website);
@FormUrlEncoded
@POST("/oauth/token")
Call<Token> createToken(
@Field("client_id") String client_id,
@Field("client_secret") String client_secret,
@Field("grant_type") String grant_type,
@Field("scrope") String scope,
@Field("username") String username,
@Field("password") String password);
@GET("/accounts/verify_credentials")
Call<AccountData.Account> verifyCredentials(@Header("Authorization") String credentials);
}

View File

@ -0,0 +1,189 @@
package app.fedilab.fedilabtube.client;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.Handler;
import android.os.Looper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import app.fedilab.fedilabtube.BuildConfig;
import app.fedilab.fedilabtube.MainActivity;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.data.AccountData;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Oauth;
import app.fedilab.fedilabtube.client.entities.OauthParams;
import app.fedilab.fedilabtube.client.entities.Token;
import app.fedilab.fedilabtube.client.entities.UserMe;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.helper.HelperInstance;
import app.fedilab.fedilabtube.sqlite.AccountDAO;
import app.fedilab.fedilabtube.sqlite.Sqlite;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitMastodonAPI {
private final String finalUrl;
private final Context _context;
private final String instance;
private String token;
public RetrofitMastodonAPI(Context context) {
_context = context;
instance = HelperInstance.getLiveInstance(context);
finalUrl = "https://" + HelperInstance.getLiveInstance(context) + "/api/v1/";
}
public RetrofitMastodonAPI(Context context, String instance, String token) {
_context = context;
this.instance = instance;
this.token = token;
finalUrl = "https://" + instance + "/api/v1/";
}
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host, String software) {
new Thread(() -> {
AccountData.Account account;
String instance = host;
try {
account = new RetrofitMastodonAPI(activity, instance, token).verifyCredentials();
} catch (Error error) {
Error.displayError(activity, error);
error.printStackTrace();
return;
}
try {
//At the state the instance can be encoded
instance = URLDecoder.decode(instance, "utf-8");
} catch (UnsupportedEncodingException ignored) {
}
SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
account.setToken(token);
account.setClient_id(client_id);
account.setClient_secret(client_secret);
account.setRefresh_token(refresh_token);
account.setHost(instance);
SQLiteDatabase db = Sqlite.getInstance(activity.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
boolean userExists = new AccountDAO(activity, db).userExist(account);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.PREF_KEY_ID, account.getId());
editor.putString(Helper.PREF_KEY_NAME, account.getUsername());
editor.apply();
if (userExists)
new AccountDAO(activity, db).updateAccountCredential(account);
else {
if (account.getUsername() != null && account.getCreatedAt() != null)
new AccountDAO(activity, db).insertAccount(account, software);
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
Intent mainActivity = new Intent(activity, MainActivity.class);
mainActivity.putExtra(Helper.INTENT_ACTION, Helper.ADD_USER_INTENT);
activity.startActivity(mainActivity);
activity.finish();
};
mainHandler.post(myRunnable);
}).start();
}
private MastodonService init() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(finalUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
if (token == null) {
token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
}
return retrofit.create(MastodonService.class);
}
/**
* Get Oauth
*
* @return APIResponse
*/
public Oauth oauthClient(String client_name, String redirect_uris, String scopes, String website) {
MastodonService mastodonService = init();
try {
Call<Oauth> oauth;
oauth = mastodonService.getOauth(client_name, redirect_uris, scopes, website);
Response<Oauth> response = oauth.execute();
if (response.isSuccessful() && response.body() != null) {
return response.body();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/***
* Verifiy credential of the authenticated user *synchronously*
* @return Account
*/
public AccountData.Account verifyCredentials() throws Error {
MastodonService mastodonService = init();
Call<AccountData.Account> accountCall = mastodonService.verifyCredentials("Bearer " + token);
APIResponse apiResponse = new APIResponse();
try {
Response<AccountData.Account> response = accountCall.execute();
if (response.isSuccessful() && response.body() != null) {
return response.body();
} else {
Error error = new Error();
error.setStatusCode(response.code());
if (response.errorBody() != null) {
error.setError(response.errorBody().string());
} else {
error.setError(_context.getString(R.string.toast_error));
}
throw error;
}
} catch (IOException e) {
Error error = new Error();
error.setError(_context.getString(R.string.toast_error));
apiResponse.setError(error);
e.printStackTrace();
}
return null;
}
/***
* Verifiy credential of the authenticated user *synchronously*
* @return Account
*/
public Token manageToken(OauthParams oauthParams) throws Error {
MastodonService mastodonService = init();
Call<Token> createToken = mastodonService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getScope(), oauthParams.getUsername(), oauthParams.getPassword());
if (createToken != null) {
try {
Response<Token> response = createToken.execute();
if (response.isSuccessful()) {
return response.body();
} else {
Error error = new Error();
error.setStatusCode(response.code());
if (response.errorBody() != null) {
error.setError(response.errorBody().string());
} else {
error.setError(_context.getString(R.string.toast_error));
}
throw error;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}

View File

@ -101,7 +101,7 @@ public class RetrofitPeertubeAPI {
private final String count;
private String token;
private Set<String> selection;
private String showNSFWVideos = "both";
private final String showNSFWVideos;
public RetrofitPeertubeAPI(Context context) {
_context = context;
@ -137,7 +137,7 @@ public class RetrofitPeertubeAPI {
}
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host) {
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host, String software) {
new Thread(() -> {
AccountData.Account account;
String instance = host;
@ -173,7 +173,7 @@ public class RetrofitPeertubeAPI {
new AccountDAO(activity, db).updateAccountCredential(account);
else {
if (account.getUsername() != null && account.getCreatedAt() != null)
new AccountDAO(activity, db).insertAccount(account);
new AccountDAO(activity, db).insertAccount(account, software);
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {

View File

@ -111,6 +111,8 @@ public class Helper {
public static final String WEBSITE_VALUE = "https://fedilab.app";
public static final String CLIENT_NAME_VALUE = "TubeLab";
public static final String OAUTH_SCOPES_PEERTUBE = "openid profile";
public static final String OAUTH_SCOPES_MASTODON = "read write follow";
public static final String REDIRECT_CONTENT = "urn:ietf:wg:oauth:2.0:oob";
public static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
public static final Pattern redirectPattern = Pattern.compile("externalAuthToken=(\\w+)&username=([\\w.-]+)");
public static final String SET_VIDEO_CACHE = "set_video_cache";

View File

@ -51,7 +51,7 @@ public class AccountDAO {
* @param account Account
* @return boolean
*/
public boolean insertAccount(Account account) {
public boolean insertAccount(Account account, String software) {
ContentValues values = new ContentValues();
if (account.getCreatedAt() == null)
account.setCreatedAt(new Date());
@ -74,6 +74,9 @@ public class AccountDAO {
values.put(Sqlite.COL_AVATAR_STATIC, "");
values.put(Sqlite.COL_HEADER, "");
values.put(Sqlite.COL_HEADER_STATIC, "");
if (software != null && software.toUpperCase().trim().compareTo("PEERTUBE") != 0) {
values.put(Sqlite.COL_SOFTWARE, software.toUpperCase().trim());
}
if (account.getClient_id() != null && account.getClient_secret() != null) {
values.put(Sqlite.COL_CLIENT_ID, account.getClient_id());
values.put(Sqlite.COL_CLIENT_SECRET, account.getClient_secret());

View File

@ -15,13 +15,19 @@ package app.fedilab.fedilabtube.sqlite;
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Sqlite extends SQLiteOpenHelper {
public static final int DB_VERSION = 3;
public static final int DB_VERSION = 4;
public static final String DB_NAME = "mastodon_etalab_db";
/***
* List of tables to manage users and data
@ -67,6 +73,7 @@ public class Sqlite extends SQLiteOpenHelper {
static final String TABLE_VIDEOS = "VIDEOS";
static final String COL_VIDEO_DATA = "VIDEO_DATA";
static final String COL_PLAYLIST_ID = "PLAYLIST_ID";
static final String COL_SOFTWARE = "SOFTWARE";
private static final String CREATE_TABLE_USER_ACCOUNT = "CREATE TABLE " + TABLE_USER_ACCOUNT + " ("
+ COL_USER_ID + " TEXT, " + COL_USERNAME + " TEXT NOT NULL, " + COL_ACCT + " TEXT NOT NULL, "
+ COL_DISPLAYED_NAME + " TEXT NOT NULL, " + COL_LOCKED + " INTEGER NOT NULL, "
@ -79,8 +86,11 @@ public class Sqlite extends SQLiteOpenHelper {
+ COL_CLIENT_ID + " TEXT, " + COL_CLIENT_SECRET + " TEXT, " + COL_REFRESH_TOKEN + " TEXT,"
+ COL_UPDATED_AT + " TEXT, "
+ COL_PRIVACY + " TEXT, "
+ COL_SOFTWARE + " TEXT NOT NULL DEFAULT \"PEERTUBE\", "
+ COL_SENSITIVE + " INTEGER DEFAULT 0, "
+ COL_INSTANCE + " TEXT NOT NULL, " + COL_OAUTHTOKEN + " TEXT NOT NULL, " + COL_CREATED_AT + " TEXT NOT NULL)";
public static SQLiteDatabase db;
private static Sqlite sInstance;
private final String CREATE_TABLE_PEERTUBE_FAVOURITES = "CREATE TABLE "
@ -136,15 +146,44 @@ public class Sqlite extends SQLiteOpenHelper {
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 4:
dropColumn(TABLE_USER_ACCOUNT, new String[]{COL_SOFTWARE});
case 3:
db.execSQL("DROP TABLE IF EXISTS " + TABLE_VIDEOS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOCAL_PLAYLISTS);
case 2:
db.execSQL("DROP TABLE IF EXISTS " + TABLE_BOOKMARKED_INSTANCES);
}
}
@SuppressWarnings("SameParameterValue")
private void dropColumn(
String tableName,
String[] colsToRemove) {
List<String> updatedTableColumns = getTableColumns(tableName);
// Remove the columns we don't want anymore from the table's list of columns
updatedTableColumns.removeAll(Arrays.asList(colsToRemove));
String columnsSeperated = TextUtils.join(",", updatedTableColumns);
db.execSQL("ALTER TABLE " + tableName + " RENAME TO " + tableName + "_old;");
// Creating the table on its new format (no redundant columns)
db.execSQL("CREATE TABLE " + tableName);
// Populating the table with the data
db.execSQL("INSERT INTO " + tableName + "(" + columnsSeperated + ") SELECT "
+ columnsSeperated + " FROM " + tableName + "_old;");
db.execSQL("DROP TABLE " + tableName + "_old;");
}
public List<String> getTableColumns(String tableName) {
ArrayList<String> columns = new ArrayList<>();
String cmd = "pragma table_info(" + tableName + ");";
Cursor cur = db.rawQuery(cmd, null);
while (cur.moveToNext()) {
columns.add(cur.getString(cur.getColumnIndex("name")));
}
cur.close();
return columns;
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
@ -153,6 +192,8 @@ public class Sqlite extends SQLiteOpenHelper {
case 2:
db.execSQL(CREATE_TABLE_LOCAL_PLAYLISTS);
db.execSQL(CREATE_TABLE_VIDEOS);
case 3:
db.execSQL("ALTER TABLE " + TABLE_USER_ACCOUNT + " ADD COLUMN " + COL_SOFTWARE + " TEXT NOT NULL DEFAULT \"PEERTUBE\"");
}
}