Cleanup overal
This commit is contained in:
parent
28576f6846
commit
c685f0a944
|
@ -2,11 +2,7 @@ package eu.stuifzand.micropub;
|
|||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerCallback;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.Application;
|
||||
import android.app.Activity;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.content.Intent;
|
||||
import android.databinding.DataBindingUtil;
|
||||
|
@ -19,26 +15,71 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.InputStream;
|
||||
|
||||
import eu.stuifzand.micropub.databinding.ActivityMainBinding;
|
||||
import eu.stuifzand.micropub.client.Client;
|
||||
import eu.stuifzand.micropub.client.Post;
|
||||
import eu.stuifzand.micropub.client.Syndication;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
import static eu.stuifzand.micropub.utils.IOUtils.getBytes;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private static final int SELECT_FILE = 12;
|
||||
private AccountManager accountManager;
|
||||
|
||||
private Account selectedAccount;
|
||||
private String authToken;
|
||||
private Client client;
|
||||
private PostViewModel postModel;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
accountManager = AccountManager.get(this);
|
||||
|
||||
AccountManager am = AccountManager.get(this);
|
||||
Bundle options = new Bundle();
|
||||
|
||||
postModel = ViewModelProviders.of(MainActivity.this).get(PostViewModel.class);
|
||||
client = ViewModelProviders.of(MainActivity.this).get(Client.class);
|
||||
|
||||
TokenReady callback = (accountType, accountName, token) -> {
|
||||
Account[] accounts = accountManager.getAccountsByType(accountType);
|
||||
if (accounts.length == 0)
|
||||
return;
|
||||
selectedAccount = accounts[0];
|
||||
authToken = token;
|
||||
|
||||
String micropubBackend = accountManager.getUserData(selectedAccount, "micropub");
|
||||
if (micropubBackend == null) return;
|
||||
|
||||
client.setToken(accountType, accountName, token);
|
||||
client.loadConfig(HttpUrl.parse(micropubBackend));
|
||||
|
||||
client.getResponse().observe(MainActivity.this, response -> {
|
||||
Log.i("micropub", "response received " + response.isSuccess());
|
||||
if (response.isSuccess()) {
|
||||
postModel.clear();
|
||||
}
|
||||
});
|
||||
|
||||
client.getMediaResponse().observe(MainActivity.this, response -> {
|
||||
Log.i("micropub", "media response received " + response.isSuccess());
|
||||
if (response.isSuccess()) {
|
||||
postModel.setPhoto(response.getUrl());
|
||||
}
|
||||
});
|
||||
};
|
||||
accountManager.getAuthTokenByFeatures("Indieauth", "token", null, this, options, null, new OnTokenAcquired(this, callback), null);
|
||||
|
||||
// setContentView(R.layout.activity_main);
|
||||
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
|
||||
PostViewModel model = ViewModelProviders.of(MainActivity.this).get(PostViewModel.class);
|
||||
Client client = ViewModelProviders.of(MainActivity.this).get(Client.class);
|
||||
binding.setViewModel(model);
|
||||
|
||||
binding.setViewModel(postModel);
|
||||
binding.setClient(client);
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
|
@ -50,9 +91,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
if (urlOrNote != null) {
|
||||
HttpUrl url = HttpUrl.parse(urlOrNote);
|
||||
if (url != null) {
|
||||
model.inReplyTo.set(urlOrNote);
|
||||
postModel.inReplyTo.set(urlOrNote);
|
||||
} else {
|
||||
model.content.set(urlOrNote);
|
||||
postModel.content.set(urlOrNote);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,16 +106,6 @@ public class MainActivity extends AppCompatActivity {
|
|||
// .setAction("Action", null).show();
|
||||
// }
|
||||
// });
|
||||
|
||||
TokenReady callback = (accountType, accountName, token) -> {
|
||||
Log.i("micropub", "TokenReady called " + accountType + " " + accountName + " " + token);
|
||||
client.setToken(accountType, accountName, token);
|
||||
client.loadSyndicates();
|
||||
};
|
||||
|
||||
AccountManager am = AccountManager.get(this);
|
||||
Bundle options = new Bundle();
|
||||
am.getAuthTokenByFeatures("Indieauth", "token", null, this, options, null, new OnTokenAcquired(callback), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,76 +135,54 @@ public class MainActivity extends AppCompatActivity {
|
|||
public void sendPost(View view) {
|
||||
AccountManager am = AccountManager.get(this);
|
||||
Bundle options = new Bundle();
|
||||
TokenReady callback = new TokenReady() {
|
||||
@Override
|
||||
public void tokenReady(String accountType, String accountName, String token) {
|
||||
|
||||
PostViewModel model = ViewModelProviders.of(MainActivity.this).get(PostViewModel.class);
|
||||
AccountManager am = AccountManager.get(MainActivity.this);
|
||||
Account[] accounts = am.getAccountsByType(accountType);
|
||||
|
||||
String micropubBackend = null;
|
||||
for (Account account : accounts) {
|
||||
if (account.name.equals(accountName)) {
|
||||
micropubBackend = am.getUserData(account, "micropub");
|
||||
}
|
||||
}
|
||||
|
||||
if (micropubBackend != null) {
|
||||
Log.i("micropub", "Sending message to " + micropubBackend);
|
||||
Client client = ViewModelProviders.of(MainActivity.this).get(Client.class);
|
||||
client.getResponse().observe(MainActivity.this, response -> {
|
||||
Log.i("micropub", "response received " + response.isSuccess());
|
||||
if (response.isSuccess()) {
|
||||
model.clear();
|
||||
}
|
||||
});
|
||||
Post post = new Post(null, model.content.get(), model.category.get(), HttpUrl.parse(model.inReplyTo.get()));
|
||||
List<String> uids = new ArrayList<String>();
|
||||
for (Syndication s : client.syndicates) {
|
||||
if (s.checked.get()) {
|
||||
uids.add(s.uid.get());
|
||||
}
|
||||
}
|
||||
post.setSyndicationUids(uids.toArray(new String[uids.size()]));
|
||||
client.createPost(post, token, HttpUrl.parse(micropubBackend));
|
||||
}
|
||||
TokenReady callback = (accountType, accountName, token) -> {
|
||||
String micropubBackend = accountManager.getUserData(selectedAccount, "micropub");
|
||||
if (micropubBackend == null) {
|
||||
Log.i("micropub", "micropub backend == null");
|
||||
return;
|
||||
}
|
||||
Log.i("micropub", "Sending message to " + micropubBackend);
|
||||
Post post = postModel.getPost();
|
||||
client.createPost(post, token, HttpUrl.parse(micropubBackend));
|
||||
};
|
||||
|
||||
am.getAuthTokenByFeatures("Indieauth", "token", null, this, options, null, new OnTokenAcquired(callback), null);
|
||||
accountManager.getAuthTokenByFeatures("Indieauth", "token", null, this, options, null, new OnTokenAcquired(this, callback), null);
|
||||
}
|
||||
|
||||
public class OnTokenAcquired implements AccountManagerCallback<Bundle> {
|
||||
private final TokenReady callback;
|
||||
public void galleryIntent(View view) {
|
||||
Intent intent = new Intent();
|
||||
intent.setType("image/*");
|
||||
intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
startActivityForResult(Intent.createChooser(intent, "Select File"), SELECT_FILE);
|
||||
}
|
||||
|
||||
public OnTokenAcquired(TokenReady callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(AccountManagerFuture<Bundle> result) {
|
||||
// Get the result of the operation from the AccountManagerFuture.
|
||||
try {
|
||||
Bundle bundle = result.getResult();
|
||||
Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
|
||||
if (launch != null) {
|
||||
MainActivity.this.startActivityForResult(launch, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// The token is a named value in the bundle. The name of the value
|
||||
// is stored in the constant AccountManager.KEY_AUTHTOKEN.
|
||||
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
Log.d("micropub", "GetTokenForAccount Bundle is " + token);
|
||||
callback.tokenReady(bundle.getString("accountType"), bundle.getString("authAccount"), token);
|
||||
} catch (OperationCanceledException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (AuthenticatorException e) {
|
||||
e.printStackTrace();
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
if (requestCode == SELECT_FILE) {
|
||||
onSelectFromGalleryResult(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onSelectFromGalleryResult(Intent data) {
|
||||
Log.i("micropub", "response received " + data.toString());
|
||||
try (InputStream input = getApplicationContext().getContentResolver().openInputStream(data.getData())) {
|
||||
byte[] output = getBytes(input);
|
||||
String mimeType = data.getType();
|
||||
if (mimeType == null) {
|
||||
mimeType = data.resolveType(getApplicationContext().getContentResolver());
|
||||
}
|
||||
|
||||
client.postMedia(output, mimeType);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e("micropub", "Error while copying image", e);
|
||||
} catch (IOException e) {
|
||||
Log.e("micropub", "Error while copying image", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
48
app/src/main/java/eu/stuifzand/micropub/OnTokenAcquired.java
Normal file
48
app/src/main/java/eu/stuifzand/micropub/OnTokenAcquired.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package eu.stuifzand.micropub;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerCallback;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
import android.accounts.AuthenticatorException;
|
||||
import android.accounts.OperationCanceledException;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OnTokenAcquired implements AccountManagerCallback<Bundle> {
|
||||
private final TokenReady callback;
|
||||
private Activity activity;
|
||||
|
||||
public OnTokenAcquired(Activity activity, TokenReady callback) {
|
||||
this.activity = activity;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(AccountManagerFuture<Bundle> result) {
|
||||
// Get the result of the operation from the AccountManagerFuture.
|
||||
try {
|
||||
Bundle bundle = result.getResult();
|
||||
Intent launch = (Intent) bundle.get(AccountManager.KEY_INTENT);
|
||||
if (launch != null) {
|
||||
activity.startActivityForResult(launch, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// The token is a named value in the bundle. The name of the value
|
||||
// is stored in the constant AccountManager.KEY_AUTHTOKEN.
|
||||
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
|
||||
Log.d("micropub", "GetTokenForAccount Bundle is " + token);
|
||||
callback.tokenReady(bundle.getString("accountType"), bundle.getString("authAccount"), token);
|
||||
} catch (OperationCanceledException e) {
|
||||
Log.e("micropub", "on token acquired", e);
|
||||
} catch (IOException e) {
|
||||
Log.e("micropub", "on token acquired", e);
|
||||
} catch (AuthenticatorException e) {
|
||||
Log.e("micropub", "on token acquired", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,6 @@ public class PostMessageTask extends AsyncTask<String, Void, String> {
|
|||
}
|
||||
|
||||
RequestBody formBody = builder.build();
|
||||
micropubBackend = "http://192.168.178.21:5000/micropub";
|
||||
Request request = new Request.Builder()
|
||||
.addHeader("Authorization", "Bearer " + accessToken)
|
||||
.method("POST", formBody)
|
||||
|
|
|
@ -8,22 +8,42 @@ import android.databinding.ObservableList;
|
|||
import java.util.Arrays;
|
||||
|
||||
import eu.stuifzand.micropub.client.Client;
|
||||
import eu.stuifzand.micropub.client.Post;
|
||||
import eu.stuifzand.micropub.client.Syndication;
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
public class PostViewModel extends ViewModel {
|
||||
public final ObservableField<String> name = new ObservableField<>();
|
||||
public final ObservableField<String> content = new ObservableField<>();
|
||||
public final ObservableField<String> category = new ObservableField<>();
|
||||
public final ObservableField<String> inReplyTo = new ObservableField<>();
|
||||
public final ObservableField<String> photo = new ObservableField<>();
|
||||
|
||||
public PostViewModel() {
|
||||
this.name.set("");
|
||||
this.content.set("");
|
||||
this.category.set("");
|
||||
this.inReplyTo.set("");
|
||||
this.photo.set("");
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.name.set("");
|
||||
this.content.set("");
|
||||
this.category.set("");
|
||||
this.inReplyTo.set("");
|
||||
this.photo.set("");
|
||||
}
|
||||
|
||||
public void setPhoto(String url) {
|
||||
this.photo.set(url);
|
||||
}
|
||||
|
||||
public Post getPost() {
|
||||
Post post = new Post(null, content.get(), category.get(), HttpUrl.parse(inReplyTo.get()));
|
||||
if (!this.photo.get().equals("")) {
|
||||
post.setPhoto(this.photo.get());
|
||||
}
|
||||
return post;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.google.gson.JsonParseException;
|
|||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.FormBody;
|
||||
|
@ -20,6 +21,7 @@ import okhttp3.Request;
|
|||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
|
||||
public class VerifyAuthenticationTask extends AsyncTask<String, Void, VerifyAuthenticationTask.AuthenticationResult> {
|
||||
|
@ -78,7 +80,16 @@ public class VerifyAuthenticationTask extends AsyncTask<String, Void, VerifyAuth
|
|||
.method("POST", formBody)
|
||||
.build();
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
Call call = client.newCall(request);
|
||||
Response response = null;
|
||||
try {
|
||||
|
|
|
@ -22,6 +22,8 @@ import java.util.regex.MatchResult;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
|
||||
public class WebsigninTask extends AsyncTask<String, Void, Bundle> {
|
||||
public static final String ME = "eu.stuifzand.micropub.ME";
|
||||
|
@ -42,10 +44,11 @@ public class WebsigninTask extends AsyncTask<String, Void, Bundle> {
|
|||
protected Bundle doInBackground(String... strings) {
|
||||
Log.i("micropub", "Starting WebsigninTask.doInBackground");
|
||||
Bundle bundle = new Bundle();
|
||||
HashMap<String,String> linkHeaders = new HashMap<>();
|
||||
HashMap<String, String> linkHeaders = new HashMap<>();
|
||||
try {
|
||||
bundle.putString(ME, strings[0]);
|
||||
Connection conn = Jsoup.connect(strings[0]);
|
||||
String profileUrl = strings[0];
|
||||
bundle.putString(ME, profileUrl);
|
||||
Connection conn = Jsoup.connect(profileUrl);
|
||||
Document doc = conn.get();
|
||||
Connection.Response resp = conn.response();
|
||||
|
||||
|
@ -61,9 +64,12 @@ public class WebsigninTask extends AsyncTask<String, Void, Bundle> {
|
|||
String url = results.group(1);
|
||||
String rel = results.group(2);
|
||||
|
||||
Log.d("micropub", "Found url=" + url + " and rel=" + rel);
|
||||
if (!rel.isEmpty() && !linkHeaders.containsKey(rel)) {
|
||||
linkHeaders.put(rel, url);
|
||||
HttpUrl base = HttpUrl.parse(profileUrl);
|
||||
HttpUrl resolvedUrl = base.resolve(url);
|
||||
|
||||
if (resolvedUrl != null && !rel.isEmpty() && !linkHeaders.containsKey(rel)) {
|
||||
Log.d("micropub", "Found url=" + resolvedUrl + " and rel=" + rel);
|
||||
linkHeaders.put(rel, resolvedUrl.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +85,7 @@ public class WebsigninTask extends AsyncTask<String, Void, Bundle> {
|
|||
return bundle;
|
||||
}
|
||||
|
||||
String[] rels = new String[]{"authorization_endpoint","token_endpoint","micropub"};
|
||||
String[] rels = new String[]{"authorization_endpoint", "token_endpoint", "micropub"};
|
||||
|
||||
for (String rel : rels) {
|
||||
if (linkHeaders.containsKey(rel)) {
|
||||
|
|
|
@ -1,111 +1,103 @@
|
|||
package eu.stuifzand.micropub.client;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.app.Application;
|
||||
import android.arch.lifecycle.AndroidViewModel;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.databinding.ObservableArrayList;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.apache.http.params.HttpParams;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import eu.stuifzand.micropub.MainActivity;
|
||||
import eu.stuifzand.micropub.TokenReady;
|
||||
import eu.stuifzand.micropub.auth.VerifyAuthenticationTask;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
public class Client extends AndroidViewModel {
|
||||
private final OkHttpClient httpClient;
|
||||
|
||||
private MutableLiveData<Response> response = new MutableLiveData<>();
|
||||
private MutableLiveData<Response> mediaResponse = new MutableLiveData<>();
|
||||
public final ObservableArrayList<Syndication> syndicates = new ObservableArrayList<>();
|
||||
|
||||
private String accountType;
|
||||
private String accountName;
|
||||
private String token;
|
||||
private HttpUrl mediaEndpoint;
|
||||
|
||||
public Client(@NonNull Application application) {
|
||||
super(application);
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
httpClient = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
|
||||
class LoadSyndicatesTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... strings) {
|
||||
AccountManager am = AccountManager.get(Client.this.getApplication());
|
||||
Account[] accounts = am.getAccountsByType(accountType);
|
||||
String micropubBackend = null;
|
||||
for (Account account : accounts) {
|
||||
if (account.name.equals(accountName)) {
|
||||
micropubBackend = am.getUserData(account, "micropub");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (micropubBackend != null) {
|
||||
HttpUrl backend = HttpUrl.parse(micropubBackend);
|
||||
backend = backend.newBuilder()
|
||||
.setQueryParameter("q", "syndicate-to")
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.addHeader("Authorization", "Bearer " + token)
|
||||
.method("GET", null)
|
||||
.url(backend)
|
||||
.build();
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
Call call = client.newCall(request);
|
||||
okhttp3.Response httpResponse = null;
|
||||
try {
|
||||
httpResponse = call.execute();
|
||||
if (httpResponse.code() == 200) {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonObject element = parser.parse(httpResponse.body().string()).getAsJsonObject();
|
||||
JsonArray arr = element.getAsJsonArray("syndicate-to");
|
||||
syndicates.clear();
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
JsonObject syn = arr.get(i).getAsJsonObject();
|
||||
syndicates.add(new Syndication(syn.get("uid").getAsString(), syn.get("name").getAsString()));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
if (httpResponse != null) {
|
||||
httpResponse.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public OkHttpClient getClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public void loadSyndicates() {
|
||||
new LoadSyndicatesTask().execute();
|
||||
public LiveData<Response> getMediaResponse() {
|
||||
return mediaResponse;
|
||||
}
|
||||
|
||||
public void loadConfig(HttpUrl micropubBackend) {
|
||||
MicropubConfigResponseCallback callback = configElement -> {
|
||||
// Media endpoint
|
||||
JsonObject config = configElement.getAsJsonObject();
|
||||
JsonElement elem = config.get("media-endpoint");
|
||||
if (elem != null) {
|
||||
setMediaEndpoint(elem.getAsString());
|
||||
}
|
||||
|
||||
// Syndications.
|
||||
JsonArray arr = config.getAsJsonArray("syndicate-to");
|
||||
if (arr != null) {
|
||||
syndicates.clear();
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
JsonObject syn = arr.get(i).getAsJsonObject();
|
||||
syndicates.add(new Syndication(syn.get("uid").getAsString(), syn.get("name").getAsString()));
|
||||
}
|
||||
}
|
||||
};
|
||||
new MicropubConfigTask(this.getClient(), micropubBackend, token, callback, "config").execute();
|
||||
}
|
||||
|
||||
public void loadSyndicates(HttpUrl micropubBackend) {
|
||||
MicropubConfigResponseCallback callback = element -> {
|
||||
JsonArray arr = element.getAsJsonObject().getAsJsonArray("syndicate-to");
|
||||
syndicates.clear();
|
||||
for (int i = 0; i < arr.size(); i++) {
|
||||
JsonObject syn = arr.get(i).getAsJsonObject();
|
||||
syndicates.add(new Syndication(syn.get("uid").getAsString(), syn.get("name").getAsString()));
|
||||
}
|
||||
};
|
||||
new MicropubConfigTask(this.getClient(), micropubBackend, token, callback, "syndicate-to").execute();
|
||||
}
|
||||
|
||||
public void createPost(Post post, String accessToken, HttpUrl micropubBackend) {
|
||||
List<String> uids = new ArrayList<String>();
|
||||
for (Syndication s : syndicates) {
|
||||
if (s.checked.get()) {
|
||||
uids.add(s.uid.get());
|
||||
}
|
||||
}
|
||||
post.setSyndicationUids(uids.toArray(new String[uids.size()]));
|
||||
|
||||
new PostTask(post, micropubBackend, accessToken, response).execute();
|
||||
}
|
||||
|
||||
|
@ -119,81 +111,11 @@ public class Client extends AndroidViewModel {
|
|||
this.token = token;
|
||||
}
|
||||
|
||||
private class PostTask extends AsyncTask<String, Void, Void> {
|
||||
public void postMedia(byte[] output, @NonNull String mimeType) {
|
||||
new PostMediaTask(mediaResponse, mediaEndpoint, token, output, mimeType).execute();
|
||||
}
|
||||
|
||||
private Post post;
|
||||
private HttpUrl micropubBackend;
|
||||
private String accessToken;
|
||||
private MutableLiveData<Response> response;
|
||||
|
||||
PostTask(Post post, HttpUrl micropubBackend, String accessToken, MutableLiveData<Response> response) {
|
||||
this.post = post;
|
||||
this.micropubBackend = micropubBackend;
|
||||
this.accessToken = accessToken;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(String... strings) {
|
||||
FormBody.Builder builder = new FormBody.Builder();
|
||||
builder.add("h", "entry")
|
||||
.add("content", post.getContent());
|
||||
|
||||
for (String cat : post.getCategories()) {
|
||||
builder.add("category[]", cat);
|
||||
}
|
||||
|
||||
for (String uid : post.getSyndicationUids()) {
|
||||
builder.add("mp-syndicate-to[]", uid);
|
||||
}
|
||||
|
||||
if (post.hasInReplyTo()) {
|
||||
builder.add("in-reply-to", post.getInReplyTo());
|
||||
}
|
||||
|
||||
if (post.hasName()) {
|
||||
builder.add("name", post.getName());
|
||||
}
|
||||
|
||||
RequestBody formBody = builder.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.addHeader("Authorization", "Bearer " + accessToken)
|
||||
.method("POST", formBody)
|
||||
.url(micropubBackend)
|
||||
.build();
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
Call call = client.newCall(request);
|
||||
okhttp3.Response httpResponse = null;
|
||||
try {
|
||||
httpResponse = call.execute();
|
||||
if (httpResponse.code() == 201) {
|
||||
String location = httpResponse.header("Location");
|
||||
response.postValue(Response.successful(location));
|
||||
} else {
|
||||
response.postValue(Response.failed());
|
||||
}
|
||||
for (Syndication s : Client.this.syndicates) {
|
||||
s.checked.set(false);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
response.postValue(Response.failed());
|
||||
} finally {
|
||||
if (httpResponse != null) {
|
||||
httpResponse.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void setMediaEndpoint(String mediaEndpoint) {
|
||||
this.mediaEndpoint = HttpUrl.parse(mediaEndpoint);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package eu.stuifzand.micropub.client;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
public interface MicropubConfigResponseCallback {
|
||||
void handleResponse(JsonElement object);
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package eu.stuifzand.micropub.client;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
|
||||
class MicropubConfigTask extends AsyncTask<String, Void, String> {
|
||||
|
||||
private final OkHttpClient client;
|
||||
private final HttpUrl micropubBackend;
|
||||
private final String accessToken;
|
||||
private final String configKey;
|
||||
private MicropubConfigResponseCallback callback;
|
||||
|
||||
public MicropubConfigTask(OkHttpClient client, HttpUrl micropubBackend, String accessToken, MicropubConfigResponseCallback callback, String configKey) {
|
||||
this.client = client;
|
||||
this.micropubBackend = micropubBackend;
|
||||
this.accessToken = accessToken;
|
||||
this.callback = callback;
|
||||
this.configKey = configKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(String... strings) {
|
||||
HttpUrl backend = micropubBackend.newBuilder()
|
||||
.setQueryParameter("q", configKey)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.addHeader("Authorization", "Bearer " + accessToken)
|
||||
.method("GET", null)
|
||||
.url(backend)
|
||||
.build();
|
||||
|
||||
Call call = client.newCall(request);
|
||||
okhttp3.Response httpResponse = null;
|
||||
|
||||
try {
|
||||
httpResponse = call.execute();
|
||||
if (httpResponse.code() == 200) {
|
||||
JsonParser parser = new JsonParser();
|
||||
JsonElement element = parser.parse(httpResponse.body().string());
|
||||
callback.handleResponse(element);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e("micropub", "Error while getting syndicate-to", e);
|
||||
} finally {
|
||||
if (httpResponse != null) {
|
||||
httpResponse.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ public class Post {
|
|||
private HttpUrl inReplyTo;
|
||||
private String[] categories;
|
||||
private String[] syndicationUids;
|
||||
private String photo;
|
||||
|
||||
public Post(String content) {
|
||||
this.content = content;
|
||||
|
@ -66,4 +67,16 @@ public class Post {
|
|||
public String[] getSyndicationUids() {
|
||||
return syndicationUids;
|
||||
}
|
||||
|
||||
public void setPhoto(String photo) {
|
||||
this.photo = photo;
|
||||
}
|
||||
|
||||
public String getPhoto() {
|
||||
return photo;
|
||||
}
|
||||
|
||||
public boolean hasPhoto() {
|
||||
return this.photo != null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package eu.stuifzand.micropub.client;
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
class PostMediaTask extends AsyncTask<String, Void, Void> {
|
||||
private MutableLiveData<Response> mediaResponse;
|
||||
private HttpUrl mediaEndpoint;
|
||||
private String accessToken;
|
||||
private byte[] output;
|
||||
private String mimeType;
|
||||
|
||||
PostMediaTask(MutableLiveData<Response> mediaResponse, HttpUrl mediaEndpoint, String accessToken, byte[] output, String mimeType) {
|
||||
this.mediaResponse = mediaResponse;
|
||||
this.mediaEndpoint = mediaEndpoint;
|
||||
this.accessToken = accessToken;
|
||||
this.output = output;
|
||||
this.mimeType = mimeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(String... strings) {
|
||||
Log.i("micropub", "output size: " + output.length);
|
||||
RequestBody formBody = new MultipartBody.Builder()
|
||||
.setType(MultipartBody.FORM)
|
||||
.addFormDataPart("file", "photo.jpg", RequestBody.create(MediaType.parse(mimeType), output))
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(mediaEndpoint)
|
||||
.addHeader("Authorization", "Bearer " + accessToken)
|
||||
.method("POST", formBody)
|
||||
.build();
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.build();
|
||||
Call call = client.newCall(request);
|
||||
try {
|
||||
okhttp3.Response httpResponse = call.execute();
|
||||
if (httpResponse.code() == 201) {
|
||||
Log.i("micropub", "response received");
|
||||
String location = httpResponse.header("Location");
|
||||
mediaResponse.postValue(Response.successful(location));
|
||||
} else {
|
||||
Log.i("micropub", httpResponse.body().string());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e("micropub", "Error while sending image", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
95
app/src/main/java/eu/stuifzand/micropub/client/PostTask.java
Normal file
95
app/src/main/java/eu/stuifzand/micropub/client/PostTask.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
package eu.stuifzand.micropub.client;
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.FormBody;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
|
||||
class PostTask extends AsyncTask<String, Void, Void> {
|
||||
|
||||
private Post post;
|
||||
private HttpUrl micropubBackend;
|
||||
private String accessToken;
|
||||
private MutableLiveData<Response> response;
|
||||
|
||||
PostTask(Post post, HttpUrl micropubBackend, String accessToken, MutableLiveData<Response> response) {
|
||||
this.post = post;
|
||||
this.micropubBackend = micropubBackend;
|
||||
this.accessToken = accessToken;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(String... strings) {
|
||||
FormBody.Builder builder = new FormBody.Builder();
|
||||
builder.add("h", "entry")
|
||||
.add("content", post.getContent());
|
||||
|
||||
for (String cat : post.getCategories()) {
|
||||
builder.add("category[]", cat);
|
||||
}
|
||||
|
||||
for (String uid : post.getSyndicationUids()) {
|
||||
builder.add("mp-syndicate-to[]", uid);
|
||||
}
|
||||
|
||||
if (post.hasInReplyTo()) {
|
||||
builder.add("in-reply-to", post.getInReplyTo());
|
||||
}
|
||||
|
||||
if (post.hasName()) {
|
||||
builder.add("name", post.getName());
|
||||
}
|
||||
|
||||
if (post.hasPhoto()) {
|
||||
builder.add("photo", post.getPhoto());
|
||||
}
|
||||
|
||||
RequestBody formBody = builder.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.addHeader("Authorization", "Bearer " + accessToken)
|
||||
.method("POST", formBody)
|
||||
.url(micropubBackend)
|
||||
.build();
|
||||
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient client = new OkHttpClient.Builder()
|
||||
.addInterceptor(logging)
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
Call call = client.newCall(request);
|
||||
okhttp3.Response httpResponse = null;
|
||||
try {
|
||||
httpResponse = call.execute();
|
||||
if (httpResponse.code() == 201) {
|
||||
String location = httpResponse.header("Location");
|
||||
response.postValue(Response.successful(location));
|
||||
} else {
|
||||
response.postValue(Response.failed());
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
response.postValue(Response.failed());
|
||||
} finally {
|
||||
if (httpResponse != null) {
|
||||
httpResponse.close();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -24,4 +24,8 @@ public class Response {
|
|||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
|
23
app/src/main/java/eu/stuifzand/micropub/utils/IOUtils.java
Normal file
23
app/src/main/java/eu/stuifzand/micropub/utils/IOUtils.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package eu.stuifzand.micropub.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class IOUtils {
|
||||
public static byte[] getBytes(InputStream inputStream) {
|
||||
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();) {
|
||||
byte[] buffer = new byte[16 * 4096];
|
||||
int read;
|
||||
while ((read = inputStream.read(buffer)) > 0) {
|
||||
outputStream.write(buffer, 0, read);
|
||||
}
|
||||
return outputStream.toByteArray();
|
||||
} catch (IOException e) {
|
||||
Log.e("micropub", "Error while copying image", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -26,15 +26,15 @@
|
|||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="always"
|
||||
android:scrollbars="vertical"
|
||||
android:paddingTop="8dp"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
|
@ -102,7 +102,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="56sp"
|
||||
android:ems="10"
|
||||
android:imeOptions="actionDone"
|
||||
android:imeOptions="actionNext"
|
||||
android:inputType="text"
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
|
@ -125,16 +125,16 @@
|
|||
android:id="@+id/textView2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/syndication"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp" />
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/listSyndication"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
android:layout_height="115dp"
|
||||
app:list="@{client.syndicates}" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -144,14 +144,48 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:onClick="sendPost"
|
||||
android:text="@string/post"
|
||||
app:layout_constraintEnd_toEndOf="@id/editCategoryLayout"
|
||||
app:layout_constraintTop_toBottomOf="@id/listLayout"
|
||||
tools:layout_editor_absoluteY="445dp" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/editPhotoLayout" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetImage"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:onClick="galleryIntent"
|
||||
android:text="Select photo"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btnPost"
|
||||
app:layout_constraintTop_toBottomOf="@+id/editPhotoLayout" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/editPhotoLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="Photo url"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/listLayout">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/editPhoto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56sp"
|
||||
android:ems="10"
|
||||
android:imeOptions="actionDone"
|
||||
android:inputType="text"
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:text="@={viewModel.photo}" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</layout>
|
Loading…
Reference in New Issue
Block a user