Added quota support

This commit is contained in:
M66B 2020-01-07 17:43:27 +01:00
parent d691bd56f1
commit 65f256a4eb
8 changed files with 2121 additions and 2 deletions

File diff suppressed because it is too large Load Diff

View File

@ -86,6 +86,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
private ImageView ivState;
private TextView tvHost;
private TextView tvLast;
private TextView tvQuota;
private TextView tvIdentity;
private TextView tvDrafts;
private TextView tvWarning;
@ -109,6 +110,7 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
ivState = itemView.findViewById(R.id.ivState);
tvHost = itemView.findViewById(R.id.tvHost);
tvLast = itemView.findViewById(R.id.tvLast);
tvQuota = itemView.findViewById(R.id.tvQuota);
tvIdentity = itemView.findViewById(R.id.tvIdentity);
tvDrafts = itemView.findViewById(R.id.tvDrafts);
tvWarning = itemView.findViewById(R.id.tvWarning);
@ -178,6 +180,10 @@ public class AdapterAccount extends RecyclerView.Adapter<AdapterAccount.ViewHold
" " + account.poll_interval +
"/" + account.keep_alive_ok +
"/" + account.keep_alive_failed : "")));
tvQuota.setText(context.getString(R.string.title_storage_quota,
(account.quota_usage == null ? "-" : Helper.humanReadableByteCount(account.quota_usage, true)),
(account.quota_limit == null ? "-" : Helper.humanReadableByteCount(account.quota_limit, true))));
tvQuota.setVisibility(account.quota_usage != null || account.quota_limit != null ? View.VISIBLE : View.GONE);
tvIdentity.setVisibility(account.identities > 0 || !settings ? View.GONE : View.VISIBLE);
tvDrafts.setVisibility(account.drafts || !settings ? View.GONE : View.VISIBLE);

View File

@ -56,7 +56,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
version = 127,
version = 128,
entities = {
EntityIdentity.class,
EntityAccount.class,
@ -1232,6 +1232,14 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `account` ADD COLUMN `keep_alive_failed` INTEGER NOT NULL DEFAULT 0");
}
})
.addMigrations(new Migration(127, 128) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase db) {
Log.i("DB migration from version " + startVersion + " to " + endVersion);
db.execSQL("ALTER TABLE `account` ADD COLUMN `quota_usage` INTEGER");
db.execSQL("ALTER TABLE `account` ADD COLUMN `quota_limit` INTEGER");
}
})
.build();
}

View File

@ -121,6 +121,9 @@ public interface DaoAccount {
@Query("UPDATE account SET last_connected = :last_connected WHERE id = :id")
int setAccountConnected(long id, long last_connected);
@Query("UPDATE account SET quota_usage = :used, quota_limit = :limit WHERE id = :id")
int setAccountQuota(long id, Long used, Long limit);
@Query("UPDATE account SET poll_interval = :value WHERE id = :id")
int setAccountKeepAliveInterval(long id, int value);

View File

@ -114,6 +114,9 @@ public class EntityAccount extends EntityOrder implements Serializable {
public Boolean use_date = false;
public String prefix; // namespace, obsolete
public Long quota_usage;
public Long quota_limit;
public Long created;
public Boolean tbd;
public String state;
@ -297,6 +300,8 @@ public class EntityAccount extends EntityOrder implements Serializable {
this.poll_interval.equals(other.poll_interval) &&
this.partial_fetch == other.partial_fetch &&
this.ignore_size == other.ignore_size &&
Objects.equals(this.quota_usage, other.quota_usage) &&
Objects.equals(this.quota_limit, other.quota_limit) &&
Objects.equals(this.created, other.created) &&
Objects.equals(this.tbd, other.tbd) &&
Objects.equals(this.state, other.state) &&

View File

@ -49,6 +49,7 @@ import androidx.lifecycle.Observer;
import androidx.preference.PreferenceManager;
import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore;
import java.io.IOException;
import java.text.DateFormat;
@ -72,6 +73,7 @@ import javax.mail.FolderNotFoundException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Quota;
import javax.mail.ReadOnlyFolderException;
import javax.mail.StoreClosedException;
import javax.mail.event.FolderAdapter;
@ -1207,6 +1209,32 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
db.account().setAccountConnected(account.id, account.last_connected);
db.account().setAccountWarning(account.id, capIdle ? null : getString(R.string.title_no_idle));
// Get quota
if (iservice.hasCapability("QUOTA"))
try {
// https://tools.ietf.org/id/draft-melnikov-extra-quota-00.html
Quota[] quotas = ((IMAPStore) iservice.getStore()).getQuota("INBOX");
if (quotas != null) {
long usage = 0;
long limit = 0;
for (Quota quota : quotas)
if (quota.resources != null)
for (Quota.Resource resource : quota.resources) {
Log.i("Quota " + resource.name + " " + resource.usage + "/" + resource.limit);
if ("STORAGE".equalsIgnoreCase(resource.name)) {
usage += resource.usage * 1024;
limit = Math.max(limit, resource.limit * 1024);
}
}
db.account().setAccountQuota(account.id, usage, limit);
}
} catch (MessagingException ex) {
Log.w(ex);
db.account().setAccountQuota(account.id, null, null);
}
else
db.account().setAccountQuota(account.id, null, null);
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
nm.cancel("receive:" + account.id, 1);
nm.cancel("alert:" + account.id, 1);

View File

@ -146,6 +146,20 @@
app:layout_constraintStart_toEndOf="@+id/ivState"
app:layout_constraintTop_toBottomOf="@id/tvHost" />
<TextView
android:id="@+id/tvQuota"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginEnd="6dp"
android:ellipsize="start"
android:singleLine="true"
android:text="123/456 MB"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/ivState"
app:layout_constraintTop_toBottomOf="@id/tvLast" />
<TextView
android:id="@+id/tvIdentity"
android:layout_width="0dp"
@ -158,7 +172,7 @@
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/vwColor"
app:layout_constraintTop_toBottomOf="@id/tvLast" />
app:layout_constraintTop_toBottomOf="@id/tvQuota" />
<TextView
android:id="@+id/tvDrafts"

View File

@ -511,6 +511,7 @@
<string name="title_edit_html">Edit as HTML</string>
<string name="title_sign_key">Sign key: %1$s</string>
<string name="title_last_connected">Last connected: %1$s</string>
<string name="title_storage_quota">Server storage usage: %1$s/%2$s</string>
<string name="title_pop_support">The POP3 protocol supports downloading and deleting messages from the inbox only. POP3 cannot mark messages as read, move messages, etc. POP3 will use more battery power and data than IMAP. So, consider using the IMAP protocol whenever possible.</string>
<string name="title_oauth_support">OAuth is not supported</string>
<string name="title_review">Review</string>