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

408 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jp.juggler.subwaytooter.App1;
import jp.juggler.subwaytooter.api.entity.TootAccount;
import jp.juggler.subwaytooter.util.LinkClickContext;
import jp.juggler.subwaytooter.util.LogCategory;
public class SavedAccount extends TootAccount implements LinkClickContext {
private static final LogCategory log = new LogCategory( "SavedAccount" );
public static final String table = "access_info";
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";
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";
// スキーマ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";
// スキーマ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";
public static final long INVALID_ID = - 1L;
// login information
public long db_id = INVALID_ID;
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;
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();
}
}
public static void onDBCreate( SQLiteDatabase db ){
db.execSQL(
"create table if not exists " + table
+ "(_id INTEGER PRIMARY KEY"
+ ",u text not null"
+ ",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"
// 以下はDBスキーマ2で追加
+ ",notification_mention integer default 1"
+ ",notification_boost integer default 1"
+ ",notification_favourite integer default 1"
+ ",notification_follow integer default 1"
// 以下は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 ''"
+ ")"
);
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)" );
}
public static void onDBUpgrade( SQLiteDatabase db, int oldVersion, int newVersion ){
if( oldVersion < 2 && newVersion >= 2 ){
try{
db.execSQL( "alter table " + table + " add column notification_mention integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
db.execSQL( "alter table " + table + " add column notification_boost integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
db.execSQL( "alter table " + table + " add column notification_favourite integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
try{
db.execSQL( "alter table " + table + " add column notification_follow integer default 1" );
}catch( Throwable ex ){
ex.printStackTrace();
}
}
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();
}
}
}
private SavedAccount(){
}
private static SavedAccount parse( Cursor cursor ) throws JSONException{
JSONObject src = new JSONObject( cursor.getString( cursor.getColumnIndex( COL_ACCOUNT ) ) );
SavedAccount dst = new SavedAccount();
dst = (SavedAccount) parse( log, dst, src, dst );
if( dst != null ){
dst.db_id = cursor.getLong( cursor.getColumnIndex( COL_ID ) );
dst.host = cursor.getString( cursor.getColumnIndex( COL_HOST ) );
dst.acct = cursor.getString( cursor.getColumnIndex( COL_USER ) );
int colIdx_visibility = cursor.getColumnIndex( COL_VISIBILITY );
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 ) ) );
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 ) ) );
}
return dst;
}
public static long insert(
@NonNull String host,
@NonNull String acct,
@NonNull JSONObject account,
@NonNull JSONObject token
){
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() );
return App1.getDB().insert( table, null, cv );
}catch( Throwable ex ){
ex.printStackTrace();
throw new RuntimeException( "SavedAccount.insert failed.", ex );
}
}
public void delete(){
try{
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 ) } );
}
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 );
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 ){
try{
Cursor cursor = App1.getDB().query( table, null, COL_ID + "=?", new String[]{ Long.toString( db_id ) }, null, null, null );
try{
if( cursor.moveToFirst() ){
return parse( cursor );
}
}finally{
cursor.close();
}
}catch( Throwable ex ){
ex.printStackTrace();
log.e( ex, "loadAccount failed." );
}
return null;
}
public static @NonNull ArrayList< SavedAccount > loadAccountList( @NonNull LogCategory log ){
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 ) );
}
}finally{
cursor.close();
}
}catch( Throwable ex ){
ex.printStackTrace();
log.e( ex, "loadAccountList failed." );
throw new RuntimeException( "SavedAccount.loadAccountList failed.", ex );
}
return result;
}
public String getFullAcct( @NonNull TootAccount who ){
return getFullAcct( who.acct );
}
public String getFullAcct( @NonNull String acct ){
if( - 1 != acct.indexOf( '@' ) ){
return acct;
}else{
return acct + "@" + this.host;
}
}
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{
return "https://" + host + "/@" + who_acct;
}
}
public boolean isMe( @NonNull TootAccount who ){
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 ){
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 ){
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 );
if( m.find() ) return AcctColor.load( m.group( 2 ) + "@" + m.group( 1 ) );
return null;
}
public static long getCount(){
try{
Cursor cursor = App1.getDB().query( table, new String[]{ "count(*)" }, null, null, null, null, null );
try{
if( cursor.moveToNext() ){
return cursor.getLong( 0 );
}
}finally{
cursor.close();
}
}catch( Throwable ex ){
ex.printStackTrace();
log.e( ex, "getCount failed." );
throw new RuntimeException( "SavedAccount.getCount failed.", ex );
}
return 0L;
}
}