added Mastodon profile updater, bug fix
This commit is contained in:
parent
84767db0e2
commit
7a9be36e79
|
@ -17,7 +17,6 @@ import org.nuclearfog.twidda.model.Trend;
|
||||||
import org.nuclearfog.twidda.model.User;
|
import org.nuclearfog.twidda.model.User;
|
||||||
import org.nuclearfog.twidda.model.UserList;
|
import org.nuclearfog.twidda.model.UserList;
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -516,20 +515,6 @@ public interface Connection {
|
||||||
*/
|
*/
|
||||||
User updateProfile(ProfileUpdate update) throws ConnectionException;
|
User updateProfile(ProfileUpdate update) throws ConnectionException;
|
||||||
|
|
||||||
/**
|
|
||||||
* update current user's profile image
|
|
||||||
*
|
|
||||||
* @param inputStream inputstream of the local image file
|
|
||||||
*/
|
|
||||||
void updateProfileImage(InputStream inputStream) throws ConnectionException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* update current user's profile banner image
|
|
||||||
*
|
|
||||||
* @param inputStream inputstream of the local image file
|
|
||||||
*/
|
|
||||||
void updateBannerImage(InputStream inputStream) throws ConnectionException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* upload media file and generate a media ID
|
* upload media file and generate a media ID
|
||||||
*
|
*
|
||||||
|
|
|
@ -95,6 +95,7 @@ public class Mastodon implements Connection {
|
||||||
private static final String ENDPOINT_NOTIFICATION = "/api/v1/notifications";
|
private static final String ENDPOINT_NOTIFICATION = "/api/v1/notifications";
|
||||||
private static final String ENDPOINT_UPLOAD_MEDIA = "/api/v2/media";
|
private static final String ENDPOINT_UPLOAD_MEDIA = "/api/v2/media";
|
||||||
private static final String ENDPOINT_MEDIA_STATUS = "/api/v1/media/";
|
private static final String ENDPOINT_MEDIA_STATUS = "/api/v1/media/";
|
||||||
|
private static final String ENDPOINT_UPDATE_CREDENTIALS = "/api/v1/accounts/update_credentials";
|
||||||
|
|
||||||
private static final MediaType TYPE_TEXT = MediaType.parse("text/plain");
|
private static final MediaType TYPE_TEXT = MediaType.parse("text/plain");
|
||||||
private static final MediaType TYPE_STREAM = MediaType.parse("application/octet-stream");
|
private static final MediaType TYPE_STREAM = MediaType.parse("application/octet-stream");
|
||||||
|
@ -352,8 +353,7 @@ public class Mastodon implements Connection {
|
||||||
List<String> params = new ArrayList<>();
|
List<String> params = new ArrayList<>();
|
||||||
params.add("q=" + StringTools.encode(search));
|
params.add("q=" + StringTools.encode(search));
|
||||||
params.add("type=statuses");
|
params.add("type=statuses");
|
||||||
params.add("following=false");
|
params.add("resolve=true");
|
||||||
params.add("offset=0");
|
|
||||||
return getStatuses(SEARCH_TIMELINE, params, minId, maxId);
|
return getStatuses(SEARCH_TIMELINE, params, minId, maxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,7 @@ public class Mastodon implements Connection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Location> getLocations() throws MastodonException {
|
public List<Location> getLocations() throws MastodonException {
|
||||||
return new ArrayList<>(0); // todo add implementation
|
return new ArrayList<>(0); // not supported yet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ public class Mastodon implements Connection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Status> getStatusReplies(String name, long id, long minId, long maxId) throws MastodonException {
|
public List<Status> getStatusReplies(String name, long id, long minId, long maxId) throws MastodonException {
|
||||||
throw new MastodonException("not implemented!"); // todo add implementation
|
return new ArrayList<>(0); // todo add implementation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -662,19 +662,31 @@ public class Mastodon implements Connection {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User updateProfile(ProfileUpdate update) throws MastodonException {
|
public User updateProfile(ProfileUpdate update) throws MastodonException {
|
||||||
throw new MastodonException("not implemented!"); // todo add implementation
|
List<String> params = new ArrayList<>();
|
||||||
|
List<InputStream> streams = new ArrayList<>();
|
||||||
|
List<String> keys = new ArrayList<>();
|
||||||
|
|
||||||
|
params.add("display_name=" + update.getName());
|
||||||
|
params.add("note=" + update.getDescription());
|
||||||
|
if (update.getProfileImageStream() != null) {
|
||||||
|
streams.add(update.getProfileImageStream());
|
||||||
|
keys.add("avatar");
|
||||||
}
|
}
|
||||||
|
if (update.getBannerImageStream() != null) {
|
||||||
|
streams.add(update.getBannerImageStream());
|
||||||
@Override
|
keys.add("header");
|
||||||
public void updateProfileImage(InputStream inputStream) throws MastodonException {
|
}
|
||||||
throw new MastodonException("not implemented!"); // todo add implementation
|
try {
|
||||||
|
Response response = patch(ENDPOINT_UPDATE_CREDENTIALS, params, streams, keys);
|
||||||
|
ResponseBody body = response.body();
|
||||||
|
if (response.code() == 200 && body != null) {
|
||||||
|
JSONObject json = new JSONObject(body.string());
|
||||||
|
return new MastodonUser(json, settings.getLogin().getId());
|
||||||
|
}
|
||||||
|
throw new MastodonException(response);
|
||||||
|
} catch (IOException | JSONException e) {
|
||||||
|
throw new MastodonException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBannerImage(InputStream inputStream) throws MastodonException {
|
|
||||||
throw new MastodonException("not implemented!"); // todo add implementation
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1026,19 +1038,8 @@ public class Mastodon implements Connection {
|
||||||
* @return http response
|
* @return http response
|
||||||
*/
|
*/
|
||||||
private Response post(String endpoint, List<String> params, InputStream is, String addToKey) throws IOException {
|
private Response post(String endpoint, List<String> params, InputStream is, String addToKey) throws IOException {
|
||||||
RequestBody data = new RequestBody() {
|
|
||||||
@Override
|
|
||||||
public MediaType contentType() {
|
|
||||||
return TYPE_STREAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(@NonNull BufferedSink sink) throws IOException {
|
|
||||||
sink.writeAll(Okio.buffer(Okio.source(is)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Account login = settings.getLogin();
|
Account login = settings.getLogin();
|
||||||
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(addToKey, StringTools.getRandomString(), data).build();
|
RequestBody body = createUploadRequest(is, addToKey);
|
||||||
return post(login.getHostname(), endpoint, login.getBearerToken(), params, body);
|
return post(login.getHostname(), endpoint, login.getBearerToken(), params, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,6 +1090,49 @@ public class Mastodon implements Connection {
|
||||||
return client.newCall(request.build()).execute();
|
return client.newCall(request.build()).execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a DELETE response
|
||||||
|
*
|
||||||
|
* @param endpoint endpoint url
|
||||||
|
* @param params additional parameters
|
||||||
|
* @return DELETE response
|
||||||
|
*/
|
||||||
|
private Response patch(String endpoint, List<String> params, List<InputStream> streams, List<String> keys) throws IOException {
|
||||||
|
Account login = settings.getLogin();
|
||||||
|
Request.Builder builder = new Request.Builder().url(buildUrl(login.getHostname(), endpoint, params));
|
||||||
|
if (streams.isEmpty() || keys.isEmpty()) {
|
||||||
|
builder.patch(RequestBody.create("", TYPE_TEXT));
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < streams.size() && i < keys.size(); i++) {
|
||||||
|
builder.patch(createUploadRequest(streams.get(i), keys.get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Request request = builder.addHeader("Authorization", "Bearer " + login.getBearerToken()).build();
|
||||||
|
return client.newCall(request).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create requestbody with upload stream
|
||||||
|
*
|
||||||
|
* @param is input stream to upload a file
|
||||||
|
* @param addToKey upload stream key
|
||||||
|
* @return request body
|
||||||
|
*/
|
||||||
|
private RequestBody createUploadRequest(final InputStream is, String addToKey) {
|
||||||
|
RequestBody data = new RequestBody() {
|
||||||
|
@Override
|
||||||
|
public MediaType contentType() {
|
||||||
|
return TYPE_STREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(@NonNull BufferedSink sink) throws IOException {
|
||||||
|
sink.writeAll(Okio.buffer(Okio.source(is)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart(addToKey, StringTools.getRandomString(), data).build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* append query parameters to an url
|
* append query parameters to an url
|
||||||
*
|
*
|
||||||
|
|
|
@ -1081,22 +1081,16 @@ public class Twitter implements Connection {
|
||||||
params.add("url=" + StringTools.encode(update.getUrl()));
|
params.add("url=" + StringTools.encode(update.getUrl()));
|
||||||
params.add("location=" + StringTools.encode(update.getLocation()));
|
params.add("location=" + StringTools.encode(update.getLocation()));
|
||||||
params.add("description=" + StringTools.encode(update.getDescription()));
|
params.add("description=" + StringTools.encode(update.getDescription()));
|
||||||
|
if (update.getProfileImageStream() != null) {
|
||||||
|
updateImage(PROFILE_UPDATE_IMAGE, update.getProfileImageStream(), "image");
|
||||||
|
}
|
||||||
|
if (update.getBannerImageStream() != null) {
|
||||||
|
updateImage(PROFILE_UPDATE_BANNER, update.getBannerImageStream(), "banner");
|
||||||
|
}
|
||||||
return getUser1(PROFILE_UPDATE, params);
|
return getUser1(PROFILE_UPDATE, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateProfileImage(InputStream inputStream) throws TwitterException {
|
|
||||||
updateImage(PROFILE_UPDATE_IMAGE, inputStream, "image");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateBannerImage(InputStream inputStream) throws TwitterException {
|
|
||||||
updateImage(PROFILE_UPDATE_BANNER, inputStream, "banner");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Long> getIdBlocklist() throws TwitterException {
|
public List<Long> getIdBlocklist() throws TwitterException {
|
||||||
// Note: the API returns up to 5000 user IDs
|
// Note: the API returns up to 5000 user IDs
|
||||||
|
|
|
@ -42,12 +42,6 @@ public class UserUpdater extends AsyncTask<Void, Void, User> {
|
||||||
@Override
|
@Override
|
||||||
protected User doInBackground(Void... v) {
|
protected User doInBackground(Void... v) {
|
||||||
try {
|
try {
|
||||||
if (profile.getProfileImageStream() != null) {
|
|
||||||
connection.updateProfileImage(profile.getProfileImageStream());
|
|
||||||
}
|
|
||||||
if (profile.getBannerImageStream() != null) {
|
|
||||||
connection.updateBannerImage(profile.getBannerImageStream());
|
|
||||||
}
|
|
||||||
User user = connection.updateProfile(profile);
|
User user = connection.updateProfile(profile);
|
||||||
// save new user information
|
// save new user information
|
||||||
db.saveUser(user);
|
db.saveUser(user);
|
||||||
|
|
|
@ -176,7 +176,6 @@ public class ProfileUpdate {
|
||||||
result += " location:\"" + location + "\"";
|
result += " location:\"" + location + "\"";
|
||||||
if (!url.isEmpty())
|
if (!url.isEmpty())
|
||||||
result += " url:\"" + url + "\"";
|
result += " url:\"" + url + "\"";
|
||||||
result += " image:" + imageAdded();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -662,6 +662,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
|
||||||
userName.setText(author.getUsername());
|
userName.setText(author.getUsername());
|
||||||
screenName.setText(author.getScreenname());
|
screenName.setText(author.getScreenname());
|
||||||
createdAt.setText(SimpleDateFormat.getDateTimeInstance().format(status.getTimestamp()));
|
createdAt.setText(SimpleDateFormat.getDateTimeInstance().format(status.getTimestamp()));
|
||||||
|
ansButton.setText(buttonNumber.format(status.getReplyCount()));
|
||||||
favButton.setText(buttonNumber.format(status.getFavoriteCount()));
|
favButton.setText(buttonNumber.format(status.getFavoriteCount()));
|
||||||
rtwButton.setText(buttonNumber.format(status.getRepostCount()));
|
rtwButton.setText(buttonNumber.format(status.getRepostCount()));
|
||||||
statusApi.setText(R.string.tweet_sent_from);
|
statusApi.setText(R.string.tweet_sent_from);
|
||||||
|
|
Loading…
Reference in New Issue