remove icon size and type
This commit is contained in:
parent
12bd524cbd
commit
a2ae6e4c21
8 changed files with 18 additions and 123 deletions
|
@ -2,11 +2,11 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 11,
|
||||
"identityHash": "5a061926458ed65c80431be0a69a2450",
|
||||
"identityHash": "31f8e6a2032d1d404fad4307abf23e1b",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "Subscription",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `lastNotificationId` TEXT, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, `displayName` TEXT, PRIMARY KEY(`id`))",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `topic` TEXT NOT NULL, `instant` INTEGER NOT NULL, `mutedUntil` INTEGER NOT NULL, `minPriority` INTEGER NOT NULL, `autoDelete` INTEGER NOT NULL, `icon` TEXT, `upAppId` TEXT, `upConnectorToken` TEXT, PRIMARY KEY(`id`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -50,12 +50,6 @@
|
|||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "lastNotificationId",
|
||||
"columnName": "lastNotificationId",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon",
|
||||
"columnName": "icon",
|
||||
|
@ -73,12 +67,6 @@
|
|||
"columnName": "upConnectorToken",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "displayName",
|
||||
"columnName": "displayName",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"primaryKey": {
|
||||
|
@ -112,7 +100,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "Notification",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_type` TEXT, `icon_size` INTEGER, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -187,30 +175,6 @@
|
|||
"affinity": "INTEGER",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.url",
|
||||
"columnName": "icon_url",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.type",
|
||||
"columnName": "icon_type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.size",
|
||||
"columnName": "icon_size",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.contentUri",
|
||||
"columnName": "icon_contentUri",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "attachment.name",
|
||||
"columnName": "attachment_name",
|
||||
|
@ -350,7 +314,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5a061926458ed65c80431be0a69a2450')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '31f8e6a2032d1d404fad4307abf23e1b')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"formatVersion": 1,
|
||||
"database": {
|
||||
"version": 12,
|
||||
"identityHash": "5a061926458ed65c80431be0a69a2450",
|
||||
"identityHash": "d230005f4d9824ba9aa34c61003bdcbb",
|
||||
"entities": [
|
||||
{
|
||||
"tableName": "Subscription",
|
||||
|
@ -112,7 +112,7 @@
|
|||
},
|
||||
{
|
||||
"tableName": "Notification",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_type` TEXT, `icon_size` INTEGER, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
|
||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `subscriptionId` INTEGER NOT NULL, `timestamp` INTEGER NOT NULL, `title` TEXT NOT NULL, `message` TEXT NOT NULL, `encoding` TEXT NOT NULL, `notificationId` INTEGER NOT NULL, `priority` INTEGER NOT NULL DEFAULT 3, `tags` TEXT NOT NULL, `click` TEXT NOT NULL, `actions` TEXT, `deleted` INTEGER NOT NULL, `icon_url` TEXT, `icon_contentUri` TEXT, `attachment_name` TEXT, `attachment_type` TEXT, `attachment_size` INTEGER, `attachment_expires` INTEGER, `attachment_url` TEXT, `attachment_contentUri` TEXT, `attachment_progress` INTEGER, PRIMARY KEY(`id`, `subscriptionId`))",
|
||||
"fields": [
|
||||
{
|
||||
"fieldPath": "id",
|
||||
|
@ -193,18 +193,6 @@
|
|||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.type",
|
||||
"columnName": "icon_type",
|
||||
"affinity": "TEXT",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.size",
|
||||
"columnName": "icon_size",
|
||||
"affinity": "INTEGER",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"fieldPath": "icon.contentUri",
|
||||
"columnName": "icon_contentUri",
|
||||
|
@ -350,7 +338,7 @@
|
|||
"views": [],
|
||||
"setupQueries": [
|
||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5a061926458ed65c80431be0a69a2450')"
|
||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd230005f4d9824ba9aa34c61003bdcbb')"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -152,8 +152,6 @@ class Backuper(val context: Context) {
|
|||
val icon = if (n.icon != null) {
|
||||
io.heckel.ntfy.db.Icon(
|
||||
url = n.icon.url,
|
||||
type = n.icon.type,
|
||||
size = n.icon.size,
|
||||
contentUri = n.icon.contentUri,
|
||||
)
|
||||
} else {
|
||||
|
@ -281,8 +279,6 @@ class Backuper(val context: Context) {
|
|||
val icon = if (n.icon != null) {
|
||||
Icon(
|
||||
url = n.icon.url,
|
||||
type = n.icon.type,
|
||||
size = n.icon.size,
|
||||
contentUri = n.icon.contentUri,
|
||||
)
|
||||
} else {
|
||||
|
@ -403,10 +399,7 @@ data class Attachment(
|
|||
|
||||
data class Icon(
|
||||
val url: String, // URL (mandatory, see ntfy server)
|
||||
val type: String?, // MIME type
|
||||
val size: Long?, // Size in bytes
|
||||
val contentUri: String?, // After it's downloaded, the content:// location
|
||||
val progress: Int, // Progress during download, -1 if not downloaded
|
||||
)
|
||||
|
||||
data class User(
|
||||
|
|
|
@ -95,12 +95,10 @@ const val ATTACHMENT_PROGRESS_DONE = 100
|
|||
@Entity
|
||||
data class Icon(
|
||||
@ColumnInfo(name = "url") val url: String, // URL (mandatory, see ntfy server)
|
||||
@ColumnInfo(name = "type") val type: String?, // MIME type
|
||||
@ColumnInfo(name = "size") val size: Long?, // Size in bytes
|
||||
@ColumnInfo(name = "contentUri") val contentUri: String?, // After it's downloaded, the content:// location
|
||||
) {
|
||||
constructor(url:String, type: String?, size: Long?) :
|
||||
this(url, type, size, null)
|
||||
constructor(url:String) :
|
||||
this(url, null)
|
||||
}
|
||||
|
||||
@Entity
|
||||
|
@ -282,8 +280,6 @@ abstract class Database : RoomDatabase() {
|
|||
db.execSQL("ALTER TABLE Subscription ADD COLUMN lastNotificationId TEXT")
|
||||
db.execSQL("ALTER TABLE Subscription ADD COLUMN displayName TEXT")
|
||||
db.execSQL("ALTER TABLE Notification ADD COLUMN icon_url TEXT") // Room limitation: Has to be nullable for @Embedded
|
||||
db.execSQL("ALTER TABLE Notification ADD COLUMN icon_type TEXT")
|
||||
db.execSQL("ALTER TABLE Notification ADD COLUMN icon_size INT")
|
||||
db.execSQL("ALTER TABLE Notification ADD COLUMN icon_contentUri TEXT")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit
|
|||
|
||||
class DownloadIconWorker(private val context: Context, params: WorkerParameters) : Worker(context, params) {
|
||||
private val client = OkHttpClient.Builder()
|
||||
.callTimeout(15, TimeUnit.MINUTES) // Total timeout for entire request
|
||||
.callTimeout(1, TimeUnit.MINUTES) // Total timeout for entire request
|
||||
.connectTimeout(15, TimeUnit.SECONDS)
|
||||
.readTimeout(15, TimeUnit.SECONDS)
|
||||
.writeTimeout(15, TimeUnit.SECONDS)
|
||||
|
@ -69,8 +69,7 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
|
|||
if (!response.isSuccessful || response.body == null) {
|
||||
throw Exception("Unexpected response: ${response.code}")
|
||||
}
|
||||
save(updateIconFromResponse(response))
|
||||
if (shouldAbortDownload()) {
|
||||
if (shouldAbortDownload(response)) {
|
||||
Log.d(TAG, "Aborting download: Content-Length is larger than auto-download setting")
|
||||
return
|
||||
}
|
||||
|
@ -85,7 +84,7 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
|
|||
val downloadLimit = if (repository.getAutoDownloadMaxSize() != Repository.AUTO_DOWNLOAD_NEVER && repository.getAutoDownloadMaxSize() != Repository.AUTO_DOWNLOAD_ALWAYS) {
|
||||
repository.getAutoDownloadMaxSize()
|
||||
} else {
|
||||
null
|
||||
MAX_ICON_DOWNLOAD_SIZE.toLong()
|
||||
}
|
||||
outFile.use { fileOut ->
|
||||
val fileIn = response.body!!.byteStream()
|
||||
|
@ -102,48 +101,14 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
|
|||
}
|
||||
Log.d(TAG, "Icon download: successful response, proceeding with download")
|
||||
save(icon.copy(
|
||||
size = bytesCopied,
|
||||
contentUri = uri.toString()
|
||||
))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
failed(e)
|
||||
|
||||
// Toast in a Worker: https://stackoverflow.com/a/56428145/1440785
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
handler.postDelayed({
|
||||
Toast
|
||||
.makeText(context, context.getString(R.string.detail_item_icon_download_failed, e.message), Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateIconFromResponse(response: Response): Icon {
|
||||
val size = if (response.headers["Content-Length"]?.toLongOrNull() != null) {
|
||||
Log.d(TAG, "We got the long! icon here")
|
||||
response.headers["Content-Length"]?.toLong()
|
||||
} else {
|
||||
icon.size // May be null!
|
||||
}
|
||||
val mimeType = if (response.headers["Content-Type"] != null) {
|
||||
response.headers["Content-Type"]
|
||||
} else {
|
||||
val ext = MimeTypeMap.getFileExtensionFromUrl(icon.url)
|
||||
if (ext != null) {
|
||||
val typeFromExt = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext)
|
||||
typeFromExt ?: icon.type // May be null!
|
||||
} else {
|
||||
icon.type // May be null!
|
||||
}
|
||||
}
|
||||
Log.d(TAG, "New icon size: $size, type: $mimeType")
|
||||
return icon.copy(
|
||||
size = size,
|
||||
type = mimeType
|
||||
)
|
||||
}
|
||||
|
||||
private fun failed(e: Exception) {
|
||||
Log.w(TAG, "Icon download failed", e)
|
||||
maybeDeleteFile()
|
||||
|
@ -166,9 +131,9 @@ class DownloadIconWorker(private val context: Context, params: WorkerParameters)
|
|||
repository.updateNotification(notification)
|
||||
}
|
||||
|
||||
private fun shouldAbortDownload(): Boolean {
|
||||
private fun shouldAbortDownload(response: Response): Boolean {
|
||||
val maxAutoDownloadSize = MAX_ICON_DOWNLOAD_SIZE
|
||||
val size = icon.size ?: return false // Don't abort if size unknown
|
||||
val size = response.headers["Content-Length"]?.toLongOrNull() ?: return false // Don't abort here if size unknown
|
||||
return size > maxAutoDownloadSize
|
||||
}
|
||||
|
||||
|
|
|
@ -60,8 +60,7 @@ class NotificationDispatcher(val context: Context, val repository: Repository) {
|
|||
Log.d(TAG, "Attachment already expired at ${attachment.expires}, not downloading")
|
||||
return false
|
||||
}
|
||||
val maxAutoDownloadSize = repository.getAutoDownloadMaxSize()
|
||||
when (maxAutoDownloadSize) {
|
||||
when (val maxAutoDownloadSize = repository.getAutoDownloadMaxSize()) {
|
||||
Repository.AUTO_DOWNLOAD_ALWAYS -> return true
|
||||
Repository.AUTO_DOWNLOAD_NEVER -> return false
|
||||
else -> {
|
||||
|
@ -73,15 +72,7 @@ class NotificationDispatcher(val context: Context, val repository: Repository) {
|
|||
}
|
||||
}
|
||||
private fun shouldDownloadIcon(notification: Notification): Boolean {
|
||||
if (notification.icon == null) {
|
||||
return false
|
||||
}
|
||||
val icon = notification.icon
|
||||
val maxIconDownloadSize = DownloadIconWorker.MAX_ICON_DOWNLOAD_SIZE
|
||||
if (icon.size == null) {
|
||||
return true // DownloadWorker will bail out if attachment is too large!
|
||||
}
|
||||
return icon.size <= maxIconDownloadSize
|
||||
return notification.icon != null
|
||||
}
|
||||
|
||||
private fun shouldNotify(subscription: Subscription, notification: Notification, muted: Boolean): Boolean {
|
||||
|
|
|
@ -52,9 +52,7 @@ class NotificationParser {
|
|||
} else null
|
||||
val icon: Icon? = if (message.icon != null) {
|
||||
Icon(
|
||||
url = message.icon,
|
||||
size = null,
|
||||
type = null
|
||||
url = message.icon
|
||||
)
|
||||
} else null
|
||||
val notification = Notification(
|
||||
|
|
|
@ -96,7 +96,7 @@ class NotificationService(val context: Context) {
|
|||
val contentUri = notification.attachment?.contentUri
|
||||
val isSupportedImage = supportedImage(notification.attachment?.type)
|
||||
val subscriptionIcon = if (subscription.icon != null) subscription.icon.readBitmapFromUriOrNull(context) else null
|
||||
val notificationIcon = if (notification.icon != null && supportedImage(notification.icon.type)) notification.icon.contentUri?.readBitmapFromUriOrNull(context) else null
|
||||
val notificationIcon = if (notification.icon != null) notification.icon.contentUri?.readBitmapFromUriOrNull(context) else null
|
||||
val largeIcon = notificationIcon ?: subscriptionIcon
|
||||
if (contentUri != null && isSupportedImage) {
|
||||
try {
|
||||
|
|
Loading…
Reference in a new issue