アカウントだけを指定した通報は動作していませんでした。メニューから削除されます。投稿時にIdempotency-Key ヘッダを付与。

This commit is contained in:
tateisu 2017-05-01 18:18:03 +09:00
parent c668bb5d7d
commit dad9a200a4
7 changed files with 158 additions and 61 deletions

View File

@ -8,6 +8,7 @@
<w>favourited</w>
<w>hashtag</w>
<w>hashtags</w>
<w>idempotency</w>
<w>noto</w>
<w>nsfw</w>
<w>reblog</w>

View File

@ -10,6 +10,7 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.customtabs.CustomTabsIntent;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.os.AsyncTaskCompat;
@ -141,6 +142,7 @@ public class ActMain extends AppCompatActivity
}
ColumnViewHolder.ListItemPopup list_item_popup;
void closeListItemPopup(){
if( list_item_popup != null ){
list_item_popup.dismiss();
@ -1739,7 +1741,9 @@ public class ActMain extends AppCompatActivity
}
private void callReport(
@NonNull final SavedAccount account
@NonNull final SavedAccount access_info
, @NonNull final TootAccount who
, @NonNull final TootStatus status
, @NonNull final String comment
, final ReportCompleteCallback callback
@ -1756,16 +1760,20 @@ public class ActMain extends AppCompatActivity
}
} );
client.setAccount( account );
client.setAccount( access_info );
StringBuilder sb = new StringBuilder();
sb.append( "account_id=" )
.append( Long.toString( who.id ) )
.append( "&comment=" )
.append( Uri.encode( comment ) );
String sb = "account_id=" + Long.toString( status.account.id )
+ "&comment=" + Uri.encode( comment )
+ "&status_ids[]=" + Long.toString( status.id );
sb.append( "&status_ids[]=" )
.append( Long.toString( status.id ) );
Request.Builder request_builder = new Request.Builder().post(
RequestBody.create(
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
, sb
, sb.toString()
) );
return client.request( "/api/v1/reports", request_builder );
@ -1789,13 +1797,13 @@ public class ActMain extends AppCompatActivity
}.execute();
}
private void openReportForm( final SavedAccount account, final TootAccount who, final TootStatus status ){
private void openReportForm( @NonNull final SavedAccount account, @NonNull final TootAccount who, @NonNull final TootStatus status ){
ReportForm.showReportForm( this, who, status, new ReportForm.ReportFormCallback() {
@Override public void startReport( final Dialog dialog, String comment ){
// レポートの送信を開始する
callReport( account, status, comment, new ReportCompleteCallback() {
callReport( account, who, status, comment, new ReportCompleteCallback() {
@Override public void onReportComplete( TootApiResult result ){
// 成功したらダイアログを閉じる
@ -1957,17 +1965,19 @@ public class ActMain extends AppCompatActivity
callBlock( access_info, status.account, false, null );
}
} );
dialog.addAction( getString( R.string.report ), new Runnable() {
@Override public void run(){
openReportForm( access_info, status.account, status );
}
} );
if( access_info.isMe( status.account ) ){
dialog.addAction( getString( R.string.delete ), new Runnable() {
@Override public void run(){
deleteStatus( access_info, status.id );
}
} );
}else{
dialog.addAction( getString( R.string.report ), new Runnable() {
@Override public void run(){
openReportForm( access_info, status.account, status );
}
} );
}
if( column_type == Column.TYPE_CONVERSATION && status.application != null ){
@ -2044,15 +2054,14 @@ public class ActMain extends AppCompatActivity
callBlock( access_info, who, false, null );
}
} );
dialog.addAction( getString( R.string.report ), new Runnable() {
@Override public void run(){
openReportForm( access_info, who, null );
}
} );
// dialog.addAction( getString( R.string.report ), new Runnable() {
// @Override public void run(){
// openReportForm( access_info, who, null );
// }
// } );
dialog.show( this, null );
}
private void openOSSLicense(){
startActivity( new Intent( this, ActOSSLicense.class ) );
}

View File

@ -940,19 +940,14 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
TootStatus status;
@Override
protected TootApiResult doInBackground( Void... params ){
@Override protected TootApiResult doInBackground( Void... params ){
TootApiClient client = new TootApiClient( ActPost.this, new TootApiClient.Callback() {
@Override
public boolean isApiCancelled(){
@Override public boolean isApiCancelled(){
return isCancelled();
}
@Override
public void publishApiProgress( final String s ){
@Override public void publishApiProgress( final String s ){
Utils.runOnMainThread( new Runnable() {
@Override
public void run(){
@Override public void run(){
progress.setMessage( s );
}
} );
@ -960,12 +955,16 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
} );
client.setAccount( target_account );
String post_content = sb.toString();
String digest = Utils.digestSHA256( post_content + target_account.acct );
Request.Builder request_builder = new Request.Builder()
.post( RequestBody.create(
TootApiClient.MEDIA_TYPE_FORM_URL_ENCODED
, sb.toString()
) );
, post_content
) )
.header( "Idempotency-Key" ,digest)
;
TootApiResult result = client.request( "/api/v1/statuses", request_builder );
if( result.object != null ){
@ -986,7 +985,7 @@ public class ActPost extends AppCompatActivity implements View.OnClickListener {
if( status != null ){
ActMain.update_at_resume = true;
ActPost.this.finish();
//DEBUG ActPost.this.finish();
}else{
if( result != null ){
Utils.showToast( ActPost.this, true, result.error );

View File

@ -17,6 +17,9 @@ import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import java.util.ArrayList;
import java.util.Collections;
import jp.juggler.subwaytooter.table.AcctSet;
import jp.juggler.subwaytooter.table.MutedApp;
import jp.juggler.subwaytooter.table.ClientInfo;
@ -26,7 +29,11 @@ import jp.juggler.subwaytooter.table.MediaShown;
import jp.juggler.subwaytooter.table.NotificationTracking;
import jp.juggler.subwaytooter.table.SavedAccount;
import jp.juggler.subwaytooter.table.UserRelation;
import okhttp3.CipherSuite;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.TlsVersion;
import okhttp3.internal.Util;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
import uk.co.chrisjenx.calligraphy.TypefaceUtils;
@ -153,7 +160,8 @@ public class App1 extends Application {
}
public static final OkHttpClient ok_http_client = new OkHttpClient();
public static OkHttpClient ok_http_client ;
public static Typeface typeface_emoji ;
@ -179,6 +187,28 @@ public class App1 extends Application {
typeface_emoji = TypefaceUtils.load(getAssets(), "emojione_android.ttf");
}
if( ok_http_client == null ){
// ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.COMPATIBLE_TLS)
// .tlsVersions( TlsVersion.TLS_1_2)
// .cipherSuites(
// CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
// CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
// CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
// .build();
//
// ArrayList<ConnectionSpec> spec_list = new ArrayList<>( );
// spec_list.add(ConnectionSpec.MODERN_TLS );
// // spec_list.add(ConnectionSpec.COMPATIBLE_TLS );
// spec_list.add(ConnectionSpec.CLEARTEXT );
// ok_http_client = new OkHttpClient.Builder()
// .connectionSpecs( spec_list )
// .build();
ok_http_client = new OkHttpClient();
}
if( db_open_helper == null ){
db_open_helper = new DBOpenHelper( getApplicationContext() );

View File

@ -111,6 +111,7 @@ public class TootApiClient {
try{
response = call.execute();
}catch( Throwable ex ){
ex.printStackTrace( );
return new TootApiResult(
Utils.formatError( ex, context.getResources(), R.string.network_error )
);
@ -183,6 +184,7 @@ public class TootApiClient {
try{
response = call.execute();
}catch( Throwable ex ){
ex.printStackTrace( );
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
}
if( callback.isApiCancelled() ) return null;
@ -266,6 +268,7 @@ public class TootApiClient {
try{
response = call.execute();
}catch( Throwable ex ){
ex.printStackTrace( );
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
}
if( callback.isApiCancelled() ) return null;
@ -306,6 +309,7 @@ public class TootApiClient {
try{
response = call.execute();
}catch( Throwable ex ){
ex.printStackTrace( );
return new TootApiResult( Utils.formatError( ex, context.getResources(), R.string.network_error ) );
}

View File

@ -74,3 +74,47 @@ public class TootAttachment {
}
}
// v1.3 から 添付ファイルの画像のピクセルサイズが取得できるようになった
// https://github.com/tootsuite/mastodon/issues/1985
// "media_attachments" : [
// {
// "id" : 4,
// "type" : "image",
// "remote_url" : "",
// "meta" : {
// "original" : {
// "width" : 600,
// "size" : "600x400",
// "height" : 400,
// "aspect" : 1.5
// },
// "small" : {
// "aspect" : 1.49812734082397,
// "height" : 267,
// "size" : "400x267",
// "width" : 400
// }
// },
// "url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/004/original/3416fc5188c656da.jpg?1493138517",
// "preview_url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/004/small/3416fc5188c656da.jpg?1493138517",
// "text_url" : "http://127.0.0.1:3000/media/4hfW3Kt4U9UxDvV_xug"
// },
// {
// "text_url" : "http://127.0.0.1:3000/media/0vTH_B1kjvIvlUBhGBw",
// "preview_url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/003/small/23519a5e64064e32.png?1493138030",
// "meta" : {
// "fps" : 15,
// "duration" : 5.06,
// "width" : 320,
// "size" : "320x180",
// "height" : 180,
// "length" : "0:00:05.06",
// "aspect" : 1.77777777777778
// },
// "url" : "http://127.0.0.1:3000/system/media_attachments/files/000/000/003/original/23519a5e64064e32.mp4?1493138030",
// "remote_url" : "",
// "type" : "gifv",
// "id" : 3
// }
// ],

View File

@ -188,7 +188,6 @@ public class Utils {
return sb;
}
static final char[] hex = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static void addHex( StringBuilder sb, byte b ){
@ -304,6 +303,18 @@ public class Utils {
return null;
}
public static String digestSHA256( String src ){
if( src == null ) return null;
try{
MessageDigest md = MessageDigest.getInstance( "SHA-256" );
md.reset();
return encodeHex( md.digest( src.getBytes( "UTF-8" ) ) );
}catch( Throwable ex ){
ex.printStackTrace();
}
return null;
}
/////////////////////////////////////////////
static HashMap< Character, String > taisaku_map = new HashMap<>();
@ -814,7 +825,6 @@ public class Utils {
return null;
}
public static Activity getActivityFromView( View view ){
Context context = view.getContext();
while( context instanceof ContextWrapper ){