fixed twitter image limit

This commit is contained in:
Mariotaku Lee 2017-06-06 09:14:14 +08:00
parent 0f100de93b
commit ae9502ad8b
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
7 changed files with 130 additions and 39 deletions

View File

@ -19,6 +19,7 @@
package org.mariotaku.microblog.library.twitter;
import org.mariotaku.microblog.library.MicroBlogException;
import org.mariotaku.microblog.library.twitter.annotation.MediaCategory;
import org.mariotaku.microblog.library.twitter.model.MediaUploadResponse;
import org.mariotaku.microblog.library.twitter.model.NewMediaMetadata;
import org.mariotaku.microblog.library.twitter.model.ResponseCode;
@ -46,7 +47,7 @@ public interface TwitterUpload {
@Params(@KeyValue(key = "command", value = "INIT"))
MediaUploadResponse initUploadMedia(@Param("media_type") String mediaType,
@Param("total_bytes") long totalBytes,
@Param("media_category") String mediaCategory,
@MediaCategory @Param("media_category") String mediaCategory,
@Param(value = "additional_owners", arrayDelimiter = ',')
String[] additionalOwners) throws MicroBlogException;

View File

@ -0,0 +1,36 @@
/*
* Twidere - Twitter client for Android
*
* Copyright 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mariotaku.microblog.library.twitter.annotation;
import android.support.annotation.StringDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@StringDef({MediaCategory.TWEET_IMAGE, MediaCategory.TWEET_GIF, MediaCategory.TWEET_VIDEO,
MediaCategory.DM_IMAGE, MediaCategory.DM_GIF, MediaCategory.DM_VIDEO})
public @interface MediaCategory {
String TWEET_IMAGE = "tweet_image";
String TWEET_GIF = "tweet_gif";
String TWEET_VIDEO = "tweet_video";
String DM_IMAGE = "dm_image";
String DM_GIF = "dm_gif";
String DM_VIDEO = "dm_video";
}

View File

@ -20,10 +20,13 @@ package org.mariotaku.twidere.model.account;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.bluelinelabs.logansquare.annotation.JsonField;
import com.bluelinelabs.logansquare.annotation.JsonObject;
import org.mariotaku.microblog.library.twitter.annotation.MediaCategory;
/**
* Created by mariotaku on 16/2/26.
*/
@ -74,6 +77,22 @@ public interface AccountExtras extends Parcelable {
this.maxSizeAsync = maxSizeAsync;
}
public boolean checkSize(long size, boolean async) {
final long limit = async ? getMaxSizeAsync() : getMaxSizeSync();
if (limit <= 0 || size <= 0) return true;
return size <= limit;
}
@Override
public String toString() {
return "ImageLimit{" +
"maxWidth=" + maxWidth +
", maxHeight=" + maxHeight +
", maxSizeSync=" + maxSizeSync +
", maxSizeAsync=" + maxSizeAsync +
'}';
}
@NonNull
public static ImageLimit ofSize(int width, int height) {
final ImageLimit limit = new ImageLimit();
@ -82,10 +101,18 @@ public interface AccountExtras extends Parcelable {
return limit;
}
public boolean checkSize(long size, boolean async) {
final long limit = async ? getMaxSizeAsync() : getMaxSizeSync();
if (limit <= 0 || size <= 0) return true;
return size <= limit;
@NonNull
public static ImageLimit twitterDefault(@Nullable @MediaCategory String category) {
if (MediaCategory.DM_IMAGE.equals(category)) {
ImageLimit limit = new ImageLimit();
limit.setMaxSizeSync(5 * 1024 * 1024);
limit.setMaxSizeAsync(5 * 1024 * 1024);
return limit;
}
final ImageLimit limit = new ImageLimit();
limit.setMaxSizeSync(3 * 1024 * 1024);
limit.setMaxSizeAsync(3 * 1024 * 1024);
return limit;
}
}
@ -320,6 +347,28 @@ public interface AccountExtras extends Parcelable {
return true;
}
@Override
public String toString() {
return "VideoLimit{" +
"supported=" + supported +
", minWidth=" + minWidth +
", minHeight=" + minHeight +
", maxWidth=" + maxWidth +
", maxHeight=" + maxHeight +
", canRotateGeometryLimit=" + canRotateGeometryLimit +
", maxSizeSync=" + maxSizeSync +
", maxSizeAsync=" + maxSizeAsync +
", minAspectRatio=" + minAspectRatio +
", maxAspectRatio=" + maxAspectRatio +
", minFrameRate=" + minFrameRate +
", maxFrameRate=" + maxFrameRate +
", minDurationSync=" + minDurationSync +
", minDurationAsync=" + minDurationAsync +
", maxDurationSync=" + maxDurationSync +
", maxDurationAsync=" + maxDurationAsync +
'}';
}
public static VideoLimit twitterDefault() {
VideoLimit videoLimit = new VideoLimit();
videoLimit.setSupported(true);

View File

@ -6,6 +6,9 @@ fun BitmapFactory.Options.calculateInSampleSize(preferredWidth: Int, preferredHe
if (preferredHeight > outHeight && preferredWidth > outWidth) {
return 1
}
if (preferredHeight <= 0 && preferredWidth <= 0) {
return 1
}
val result = Math.round(Math.max(outWidth, outHeight) / Math.max(preferredWidth, preferredHeight).toFloat())
return Math.max(1, result)
}

View File

@ -2,6 +2,7 @@ package org.mariotaku.twidere.extension.model
import android.content.Context
import com.twitter.Validator
import org.mariotaku.microblog.library.twitter.annotation.MediaCategory
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.model.AccountDetails
import org.mariotaku.twidere.model.account.AccountExtras
@ -41,34 +42,33 @@ fun <T> AccountDetails.newMicroBlogInstance(context: Context, cls: Class<T>): T
val AccountDetails.isOAuth: Boolean
get() = credentials_type == Credentials.Type.OAUTH || credentials_type == Credentials.Type.XAUTH
val AccountDetails.mediaSizeLimit: UpdateStatusTask.SizeLimit?
get() {
when (type) {
AccountType.TWITTER -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.twitterDefault()
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
AccountType.FANFOU -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.unsupported()
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
AccountType.STATUSNET -> {
val extras = extras as? StatusNetAccountExtras ?: return null
val imageLimit = AccountExtras.ImageLimit().apply {
maxSizeSync = extras.uploadLimit
maxSizeAsync = extras.uploadLimit
}
val videoLimit = AccountExtras.VideoLimit().apply {
maxSizeSync = extras.uploadLimit
maxSizeAsync = extras.uploadLimit
}
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
else -> return null
fun AccountDetails.getMediaSizeLimit(@MediaCategory mediaCategory: String? = null): UpdateStatusTask.SizeLimit? {
when (type) {
AccountType.TWITTER -> {
val imageLimit = AccountExtras.ImageLimit.twitterDefault(mediaCategory)
val videoLimit = AccountExtras.VideoLimit.twitterDefault()
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
AccountType.FANFOU -> {
val imageLimit = AccountExtras.ImageLimit.ofSize(2048, 1536)
val videoLimit = AccountExtras.VideoLimit.unsupported()
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
AccountType.STATUSNET -> {
val extras = extras as? StatusNetAccountExtras ?: return null
val imageLimit = AccountExtras.ImageLimit().apply {
maxSizeSync = extras.uploadLimit
maxSizeAsync = extras.uploadLimit
}
val videoLimit = AccountExtras.VideoLimit().apply {
maxSizeSync = extras.uploadLimit
maxSizeAsync = extras.uploadLimit
}
return UpdateStatusTask.SizeLimit(imageLimit, videoLimit)
}
else -> return null
}
}
/**
* Text limit when composing a status, 0 for no limit

View File

@ -43,7 +43,7 @@ import org.mariotaku.twidere.extension.calculateInSampleSize
import org.mariotaku.twidere.extension.model.api.mastodon.toParcelable
import org.mariotaku.twidere.extension.model.api.toParcelable
import org.mariotaku.twidere.extension.model.applyUpdateStatus
import org.mariotaku.twidere.extension.model.mediaSizeLimit
import org.mariotaku.twidere.extension.model.getMediaSizeLimit
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
import org.mariotaku.twidere.extension.model.textLimit
import org.mariotaku.twidere.extension.text.twitter.getTweetLength
@ -305,7 +305,7 @@ class UpdateStatusTask(
if (statusUpdate.media.isNotNullOrEmpty()) {
// Fanfou only allow one photo
fanfouUpdateStatusWithPhoto(microBlog, statusUpdate, pendingUpdate,
account.mediaSizeLimit, i)
account.getMediaSizeLimit(), i)
} else {
twitterUpdateStatus(microBlog, statusUpdate, pendingUpdate, i)
}
@ -712,7 +712,7 @@ class UpdateStatusTask(
//noinspection TryWithIdenticalCatches
var body: MediaStreamBody? = null
try {
val sizeLimit = account.mediaSizeLimit
val sizeLimit = account.getMediaSizeLimit(mediaCategory)
body = getBodyFromMedia(context, media, sizeLimit, chucked,
ContentLengthInputStream.ReadListener { length, position ->
callback?.onUploadingProgressChanged(index, position, length)
@ -758,7 +758,7 @@ class UpdateStatusTask(
//noinspection TryWithIdenticalCatches
var body: MediaStreamBody? = null
try {
val sizeLimit = account.mediaSizeLimit
val sizeLimit = account.getMediaSizeLimit()
body = getBodyFromMedia(context, media, sizeLimit, chucked,
ContentLengthInputStream.ReadListener { length, position ->
callback?.onUploadingProgressChanged(index, position, length)
@ -931,7 +931,7 @@ class UpdateStatusTask(
when (mediaType) {
"image/png", "image/x-png", "image/webp", "image-x-webp" -> {
tempFile.outputStream().use { os ->
bitmap.compress(Bitmap.CompressFormat.PNG, 0, os)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, os)
}
}
"image/jpeg" -> {
@ -939,6 +939,7 @@ class UpdateStatusTask(
.use(::ExifInterface)
tempFile.outputStream().use { os ->
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, os)
os.flush()
}
val orientation = origExif.getAttribute(ExifInterface.TAG_ORIENTATION)
if (orientation != null) {

View File

@ -24,6 +24,7 @@ import org.mariotaku.ktextension.isNotNullOrEmpty
import org.mariotaku.microblog.library.MicroBlog
import org.mariotaku.microblog.library.MicroBlogException
import org.mariotaku.microblog.library.twitter.TwitterUpload
import org.mariotaku.microblog.library.twitter.annotation.MediaCategory
import org.mariotaku.microblog.library.twitter.model.DirectMessage
import org.mariotaku.microblog.library.twitter.model.NewDm
import org.mariotaku.sqliteqb.library.Expression
@ -143,9 +144,9 @@ class SendMessageTask(
message: ParcelableNewMessage): GetMessagesTask.DatabaseUpdateData {
val recipientId = message.recipient_ids.singleOrNull() ?: throw MicroBlogException("No recipient")
val category = when (message.media?.firstOrNull()?.type) {
ParcelableMedia.Type.IMAGE -> "dm_image"
ParcelableMedia.Type.VIDEO -> "dm_video"
ParcelableMedia.Type.ANIMATED_GIF -> "dm_gif"
ParcelableMedia.Type.IMAGE -> MediaCategory.DM_IMAGE
ParcelableMedia.Type.VIDEO -> MediaCategory.DM_VIDEO
ParcelableMedia.Type.ANIMATED_GIF -> MediaCategory.DM_GIF
else -> null
}
val response = uploadMediaThen(account, message, category) { mediaId ->