SubwayTooter-Android-App/app/src/main/java/jp/juggler/subwaytooter/table/SavedAccount.java

408 lines
14 KiB
Java
Raw Normal View History

2017-04-20 18:23:59 +02:00
package jp.juggler.subwaytooter.table;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
2017-04-20 18:23:59 +02:00
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
2017-04-20 18:23:59 +02:00
import jp.juggler.subwaytooter.App1;
import jp.juggler.subwaytooter.api.entity.TootAccount;
import jp.juggler.subwaytooter.util.LinkClickContext;
2017-04-20 18:23:59 +02:00
import jp.juggler.subwaytooter.util.LogCategory;
2017-04-26 02:49:20 +02:00
public class SavedAccount extends TootAccount implements LinkClickContext {
private static final LogCategory log = new LogCategory( "SavedAccount" );
2017-04-20 18:23:59 +02:00
public static final String table = "access_info";
2017-04-20 18:23:59 +02:00
private static final String COL_ID = BaseColumns._ID;
private static final String COL_HOST = "h";
private static final String COL_USER = "u";
private static final String COL_ACCOUNT = "a";
private static final String COL_TOKEN = "t";
2017-04-26 02:49:20 +02:00
private static final String COL_VISIBILITY = "visibility";
private static final String COL_CONFIRM_BOOST = "confirm_boost";
private static final String COL_DONT_HIDE_NSFW = "dont_hide_nsfw";
2017-05-04 01:11:05 +02:00
// スキーマ2から
private static final String COL_NOTIFICATION_MENTION = "notification_mention";
private static final String COL_NOTIFICATION_BOOST = "notification_boost";
private static final String COL_NOTIFICATION_FAVOURITE = "notification_favourite";
private static final String COL_NOTIFICATION_FOLLOW = "notification_follow";
2017-05-04 01:11:05 +02:00
// スキーマ10から
private static final String COL_CONFIRM_FOLLOW = "confirm_follow";
private static final String COL_CONFIRM_FOLLOW_LOCKED = "confirm_follow_locked";
private static final String COL_CONFIRM_UNFOLLOW = "confirm_unfollow";
private static final String COL_CONFIRM_POST = "confirm_post";
// スキーマ13から
private static final String COL_NOTIFICATION_TAG = "notification_server";
2017-04-20 18:23:59 +02:00
2017-04-26 02:49:20 +02:00
public static final long INVALID_ID = - 1L;
2017-04-20 18:23:59 +02:00
// login information
public long db_id = INVALID_ID;
2017-04-20 18:23:59 +02:00
public String host;
public String acct; // user@host
public JSONObject token_info;
public String visibility;
public boolean confirm_boost;
public boolean dont_hide_nsfw;
public boolean notification_mention;
public boolean notification_boost;
public boolean notification_favourite;
public boolean notification_follow;
2017-04-20 18:23:59 +02:00
2017-05-04 01:11:05 +02:00
public boolean confirm_follow;
public boolean confirm_follow_locked;
public boolean confirm_unfollow;
public boolean confirm_post;
public String notification_tag;
// アプリデータのインポート時に呼ばれる
public static void onDBDelete( SQLiteDatabase db ){
try{
db.execSQL( "drop table if exists " + table );
}catch( Throwable ex ){
ex.printStackTrace();
}
}
2017-04-20 18:23:59 +02:00
public static void onDBCreate( SQLiteDatabase db ){
db.execSQL(
"create table if not exists " + table
+ "(_id INTEGER PRIMARY KEY"
+ ",u text not null"
2017-04-20 18:23:59 +02:00
+ ",h text not null"
+ ",a text not null"
+ ",t text not null"
+ ",visibility text"
+ ",confirm_boost integer default 1"
+ ",dont_hide_nsfw integer default 0"
2017-05-04 01:11:05 +02:00
// 以下はDBスキーマ2で追加
+ ",notification_mention integer default 1"
+ ",notification_boost integer default 1"
+ ",notification_favourite integer default 1"
+ ",notification_follow integer default 1"
2017-05-04 01:11:05 +02:00
// 以下はDBスキーマ10で更新
+ "," + COL_CONFIRM_FOLLOW + " integer default 1"
+ "," + COL_CONFIRM_FOLLOW_LOCKED + " integer default 1"
+ "," + COL_CONFIRM_UNFOLLOW + " integer default 1"
+ "," + COL_CONFIRM_POST + " integer default 1"
// 以下はDBスキーマ13で更新
+ "," + COL_NOTIFICATION_TAG + " text default ''"
2017-04-20 18:23:59 +02:00
+ ")"
);
2017-04-26 02:49:20 +02:00
db.execSQL( "create index if not exists " + table + "_user on " + table + "(u)" );
db.execSQL( "create index if not exists " + table + "_host on " + table + "(h,u)" );
2017-04-20 18:23:59 +02:00
}
public static void onDBUpgrade( SQLiteDatabase db, int oldVersion, int newVersion ){
2017-04-26 02:49:20 +02:00
if( oldVersion < 2 && newVersion >= 2 ){
try{
2017-04-26 02:49:20 +02:00
db.execSQL( "alter table " + table + " add column notification_mention integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
2017-04-26 02:49:20 +02:00
db.execSQL( "alter table " + table + " add column notification_boost integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
2017-04-26 02:49:20 +02:00
db.execSQL( "alter table " + table + " add column notification_favourite integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
2017-04-26 02:49:20 +02:00
db.execSQL( "alter table " + table + " add column notification_follow integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
}
2017-05-04 01:11:05 +02:00
if( oldVersion < 10 && newVersion >= 10 ){
try{
db.execSQL( "alter table " + table + " add column " + COL_CONFIRM_FOLLOW + " integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
db.execSQL( "alter table " + table + " add column " + COL_CONFIRM_FOLLOW_LOCKED + " integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
db.execSQL( "alter table " + table + " add column " + COL_CONFIRM_UNFOLLOW + " integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
db.execSQL( "alter table " + table + " add column " + COL_CONFIRM_POST + " integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
}
if( oldVersion < 13 && newVersion >= 13 ){
try{
db.execSQL( "alter table " + table + " add column " + COL_NOTIFICATION_TAG + " text default ''" );
}catch( Throwable ex ){
ex.printStackTrace();
}
}
2017-04-20 18:23:59 +02:00
}
private SavedAccount(){
}
2017-04-26 02:49:20 +02:00
private static SavedAccount parse( Cursor cursor ) throws JSONException{
2017-04-20 18:23:59 +02:00
JSONObject src = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_ACCOUNT ) ) );
SavedAccount dst = new SavedAccount();
2017-04-26 02:49:20 +02:00
dst = (SavedAccount) parse( log, dst, src, dst );
if( dst != null ){
dst.db_id = cursor.getLong( cursor.getColumnIndex( COL_ID ) );
2017-04-20 18:23:59 +02:00
dst.host = cursor.getString( cursor.getColumnIndex( COL_HOST ) );
dst.acct = cursor.getString( cursor.getColumnIndex( COL_USER ) );
int colIdx_visibility = cursor.getColumnIndex( COL_VISIBILITY );
2017-04-26 02:49:20 +02:00
dst.visibility = cursor.isNull( colIdx_visibility ) ? null : cursor.getString( colIdx_visibility );
dst.confirm_boost = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_BOOST ) ) );
dst.dont_hide_nsfw = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_DONT_HIDE_NSFW ) ) );
dst.notification_mention = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_NOTIFICATION_MENTION ) ) );
dst.notification_boost = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_NOTIFICATION_BOOST ) ) );
dst.notification_favourite = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_NOTIFICATION_FAVOURITE ) ) );
dst.notification_follow = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_NOTIFICATION_FOLLOW ) ) );
2017-05-04 01:11:05 +02:00
dst.confirm_follow = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_FOLLOW ) ) );
dst.confirm_follow_locked = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_FOLLOW_LOCKED ) ) );
dst.confirm_unfollow = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_UNFOLLOW ) ) );
dst.confirm_post = ( 0 != cursor.getInt( cursor.getColumnIndex( COL_CONFIRM_POST ) ) );
int idx_notification_tag = cursor.getColumnIndex( COL_NOTIFICATION_TAG );
dst.notification_tag = cursor.isNull(idx_notification_tag) ? null : cursor.getString( idx_notification_tag );
dst.token_info = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_TOKEN ) ) );
2017-04-20 18:23:59 +02:00
}
return dst;
}
public static long insert(
@NonNull String host,
@NonNull String acct,
@NonNull JSONObject account,
@NonNull JSONObject token
){
2017-04-20 18:23:59 +02:00
try{
ContentValues cv = new ContentValues();
cv.put( COL_HOST, host );
cv.put( COL_USER, acct );
cv.put( COL_ACCOUNT, account.toString() );
cv.put( COL_TOKEN, token.toString() );
2017-04-26 02:49:20 +02:00
return App1.getDB().insert( table, null, cv );
2017-04-20 18:23:59 +02:00
}catch( Throwable ex ){
ex.printStackTrace();
throw new RuntimeException( "SavedAccount.insert failed.", ex );
2017-04-20 18:23:59 +02:00
}
}
public void delete(){
try{
2017-04-26 02:49:20 +02:00
App1.getDB().delete( table, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
}catch( Throwable ex ){
ex.printStackTrace();
throw new RuntimeException( "SavedAccount.delete failed.", ex );
}
}
public void updateTokenInfo( @NonNull JSONObject token_info ){
if( db_id == INVALID_ID )
throw new RuntimeException( "SavedAccount.updateTokenInfo missing db_id" );
this.token_info = token_info;
ContentValues cv = new ContentValues();
cv.put( COL_TOKEN, token_info.toString() );
App1.getDB().update( table, cv, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
}
2017-04-26 02:49:20 +02:00
public void saveSetting(){
if( db_id == INVALID_ID )
throw new RuntimeException( "SavedAccount.saveSetting missing db_id" );
ContentValues cv = new ContentValues();
cv.put( COL_VISIBILITY, visibility );
cv.put( COL_CONFIRM_BOOST, confirm_boost ? 1 : 0 );
cv.put( COL_DONT_HIDE_NSFW, dont_hide_nsfw ? 1 : 0 );
cv.put( COL_NOTIFICATION_MENTION, notification_mention ? 1 : 0 );
cv.put( COL_NOTIFICATION_BOOST, notification_boost ? 1 : 0 );
cv.put( COL_NOTIFICATION_FAVOURITE, notification_favourite ? 1 : 0 );
cv.put( COL_NOTIFICATION_FOLLOW, notification_follow ? 1 : 0 );
2017-05-04 01:11:05 +02:00
cv.put( COL_CONFIRM_FOLLOW, confirm_follow ? 1 : 0 );
cv.put( COL_CONFIRM_FOLLOW_LOCKED, confirm_follow_locked ? 1 : 0 );
cv.put( COL_CONFIRM_UNFOLLOW, confirm_unfollow ? 1 : 0 );
cv.put( COL_CONFIRM_POST, confirm_post ? 1 : 0 );
if( notification_tag != null ) cv.put( COL_NOTIFICATION_TAG, notification_tag );
App1.getDB().update( table, cv, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
}
public void saveNotificationTag(){
if( db_id == INVALID_ID )
throw new RuntimeException( "SavedAccount.saveSetting missing db_id" );
ContentValues cv = new ContentValues();
cv.put( COL_NOTIFICATION_TAG, notification_tag );
App1.getDB().update( table, cv, COL_ID + "=?", new String[]{ Long.toString( db_id ) } );
}
// onResumeの時に設定を読み直す
public void reloadSetting(){
if( db_id == INVALID_ID )
throw new RuntimeException( "SavedAccount.reloadSetting missing db_id" );
SavedAccount b = loadAccount( log, db_id );
if( b == null ) return; // DBから削除されてる
this.visibility = b.visibility;
this.confirm_boost = b.confirm_boost;
this.dont_hide_nsfw = b.dont_hide_nsfw;
this.token_info = b.token_info;
this.notification_mention = b.notification_follow;
this.notification_boost = b.notification_boost;
this.notification_favourite = b.notification_favourite;
this.notification_follow = b.notification_follow;
this.notification_tag = b.notification_tag;
}
public static @Nullable SavedAccount loadAccount( @NonNull LogCategory log, long db_id ){
2017-04-20 18:23:59 +02:00
try{
2017-04-26 02:49:20 +02:00
Cursor cursor = App1.getDB().query( table, null, COL_ID + "=?", new String[]{ Long.toString( db_id ) }, null, null, null );
2017-04-20 18:23:59 +02:00
try{
if( cursor.moveToFirst() ){
return parse( cursor );
2017-04-20 18:23:59 +02:00
}
}finally{
cursor.close();
}
}catch( Throwable ex ){
ex.printStackTrace();
log.e( ex, "loadAccount failed." );
2017-04-20 18:23:59 +02:00
}
return null;
}
2017-04-26 02:49:20 +02:00
public static @NonNull ArrayList< SavedAccount > loadAccountList( @NonNull LogCategory log ){
2017-04-20 18:23:59 +02:00
ArrayList< SavedAccount > result = new ArrayList<>();
try{
Cursor cursor = App1.getDB().query( table, null, null, null, null, null, null );
try{
while( cursor.moveToNext() ){
result.add( parse( cursor ) );
2017-04-20 18:23:59 +02:00
}
}finally{
cursor.close();
}
}catch( Throwable ex ){
ex.printStackTrace();
2017-04-20 18:23:59 +02:00
log.e( ex, "loadAccountList failed." );
throw new RuntimeException( "SavedAccount.loadAccountList failed.", ex );
2017-04-20 18:23:59 +02:00
}
return result;
2017-04-20 18:23:59 +02:00
}
public String getFullAcct( @NonNull TootAccount who ){
return getFullAcct( who.acct );
2017-04-23 07:42:09 +02:00
}
public String getFullAcct( @NonNull String acct ){
2017-04-26 02:49:20 +02:00
if( - 1 != acct.indexOf( '@' ) ){
return acct;
2017-04-20 18:23:59 +02:00
}else{
2017-04-26 02:49:20 +02:00
return acct + "@" + this.host;
2017-04-20 18:23:59 +02:00
}
}
public String getUserUrl( @NonNull String who_acct ){
int p = who_acct.indexOf( '@' );
if( - 1 != p ){
return "https://" + who_acct.substring( p + 1 ) + "/@" + who_acct.substring( 0, p );
}else{
2017-05-06 08:10:05 +02:00
return "https://" + host + "/@" + who_acct;
}
}
public boolean isMe( @NonNull TootAccount who ){
2017-04-26 02:49:20 +02:00
int pos = this.acct.indexOf( '@' );
String this_user = this.acct.substring( 0, pos );
//
if( ! this_user.equals( who.username ) ) return false;
//
pos = who.acct.indexOf( '@' );
return pos == - 1 || this.host.equalsIgnoreCase( who.acct.substring( pos + 1 ) );
}
public boolean isMe( @NonNull String who_acct ){
2017-04-26 02:49:20 +02:00
int pos = this.acct.indexOf( '@' );
String this_user = this.acct.substring( 0, pos );
//
pos = who_acct.indexOf( '@' );
if( pos == - 1 ) return this_user.equals( who_acct );
//
return this_user.equals( who_acct.substring( 0, pos ) )
&& this.host.equalsIgnoreCase( who_acct.substring( pos + 1 ) );
}
public String supplyBaseUrl( String url ){
2017-05-04 01:11:05 +02:00
if( TextUtils.isEmpty( url ) ) return url;
if( url.charAt( 0 ) == '/' ) return "https://" + host + url;
return url;
}
public boolean isPseudo(){
return "?".equals( username );
}
private static final Pattern reAcctUrl = Pattern.compile( "\\Ahttps://([A-Za-z0-9.-]+)/@([A-Za-z0-9_]+)\\z" );
@Override public AcctColor findAcctColor( String url ){
Matcher m = reAcctUrl.matcher( url );
2017-05-04 01:11:05 +02:00
if( m.find() ) return AcctColor.load( m.group( 2 ) + "@" + m.group( 1 ) );
return null;
}
2017-05-15 15:15:00 +02:00
public static long getCount(){
try{
Cursor cursor = App1.getDB().query( table, new String[]{ "count(*)" }, null, null, null, null, null );
2017-05-15 15:15:00 +02:00
try{
if( cursor.moveToNext() ){
return cursor.getLong( 0 );
2017-05-15 15:15:00 +02:00
}
}finally{
cursor.close();
}
}catch( Throwable ex ){
ex.printStackTrace();
log.e( ex, "getCount failed." );
throw new RuntimeException( "SavedAccount.getCount failed.", ex );
}
return 0L;
}
2017-04-20 18:23:59 +02:00
}