pub struct Attachment {
pub rowid: i32,
pub guid: Option<String>,
pub filename: Option<String>,
pub uti: Option<String>,
pub mime_type: Option<String>,
pub transfer_name: Option<String>,
pub total_bytes: i64,
pub is_sticker: bool,
pub hide_attachment: i32,
pub emoji_description: Option<String>,
pub copied_path: Option<PathBuf>,
}Expand description
Row from the attachment table.
Fields§
§rowid: i32Attachment row ID.
guid: Option<String>The attachment’s GUID. Matches the __kIMFileTransferGUIDAttributeName
carried on the message body’s attachment ranges, letting the exporter
pair a body placeholder with its resolved attachment by identity rather
than by position.
filename: Option<String>Path to the file on disk as stored in the database.
uti: Option<String>§mime_type: Option<String>MIME type string.
transfer_name: Option<String>Original transfer filename.
total_bytes: i64Total bytes recorded by Messages.
is_sticker: booltrue when the attachment is a sticker.
hide_attachment: i32Messages UI hide flag.
emoji_description: Option<String>Prompt used to generate a Genmoji.
copied_path: Option<PathBuf>Auxiliary data to denote that an attachment has been copied or converted.
Implementations§
Source§impl Attachment
impl Attachment
Sourcepub fn from_message(
db: &Connection,
msg: &Message,
) -> Result<Vec<Attachment>, TableError>
pub fn from_message( db: &Connection, msg: &Message, ) -> Result<Vec<Attachment>, TableError>
Load attachments associated with one message.
Rows are returned in the message_attachment_join table’s order, which is
not guaranteed to align with the order of the attachment
AttributedRanges
(those whose attachment
is Some) in the message’s
attributed_body().
Callers pairing body ranges to rows should match on the file-transfer GUID
rather than relying on position.
Sourcepub fn is_animated_sticker(&self) -> bool
pub fn is_animated_sticker(&self) -> bool
true when this sticker’s underlying file is animated: a HEIC
sequence (image/heics, image/heic-sequence) or a video
(video/*). Static stickers (HEIC, PNG, etc.) return false.
Renderer presentation decisions are the caller’s concern.
Sourcepub fn as_bytes(
&self,
platform: &Platform,
db_path: &Path,
custom_attachment_root: Option<&str>,
) -> Result<Option<Vec<u8>>, AttachmentError>
pub fn as_bytes( &self, platform: &Platform, db_path: &Path, custom_attachment_root: Option<&str>, ) -> Result<Option<Vec<u8>>, AttachmentError>
Read the attachment file into memory.
db_path is the path to the root of the backup directory.
This is the same path used by get_connection().
Sourcepub fn get_sticker_effect(
&self,
platform: &Platform,
db_path: &Path,
custom_attachment_root: Option<&str>,
) -> Result<Option<StickerEffect>, AttachmentError>
pub fn get_sticker_effect( &self, platform: &Platform, db_path: &Path, custom_attachment_root: Option<&str>, ) -> Result<Option<StickerEffect>, AttachmentError>
Parse the StickerEffect for a sticker attachment.
db_path is the path to the root of the backup directory.
This is the same path used by get_connection().
Sourcepub fn filename(&self) -> Option<&str>
pub fn filename(&self) -> Option<&str>
Return the transfer filename, falling back to the stored path.
transfer_name is the display filename when present; filename is the
database path.
Sourcepub fn file_size(&self) -> String
pub fn file_size(&self) -> String
Return total_bytes as a human-readable size.
Sourcepub fn get_total_attachment_bytes(
db: &Connection,
context: &QueryContext,
) -> Result<u64, TableError>
pub fn get_total_attachment_bytes( db: &Connection, context: &QueryContext, ) -> Result<u64, TableError>
Sum attachment bytes, applying date filters from QueryContext.
Sourcepub fn resolved_attachment_path(
&self,
platform: &Platform,
db_path: &Path,
custom_attachment_root: Option<&str>,
) -> Option<String>
pub fn resolved_attachment_path( &self, platform: &Platform, db_path: &Path, custom_attachment_root: Option<&str>, ) -> Option<String>
Resolve the on-disk path for this attachment.
For macOS, db_path is unused. For iOS, db_path is the path to the root of the backup directory.
This is the same path used by get_connection().
On encrypted iOS backups, file names are derived from the SHA-1 hash of
MediaDomain- plus the relative filename. Read more here.
Use the optional custom_attachment_root parameter when attachment data is stored under a
different Messages root than the database expects. This replaces the leading Messages root,
not just the Attachments directory, so it affects both DEFAULT_ATTACHMENT_ROOT and
DEFAULT_STICKER_CACHE_ROOT.
For example, a custom attachment root like /custom/path will rewrite
~/Library/Messages/Attachments/3d/... to /custom/path/Attachments/3d/... and
~/Library/Messages/StickerCache/ab/... to /custom/path/StickerCache/ab/....
For a jailbroken iOS sms.db, attachment paths start with DEFAULT_SMS_ROOT (~/Library/SMS)
instead of DEFAULT_MESSAGES_ROOT. These databases behave like macOS databases and should
use Platform::macOS, not Platform::iOS, which is reserved for encrypted Finder/Apple Devices/iTunes backups.
Sourcepub fn run_diagnostic(
db: &Connection,
db_path: &Path,
platform: &Platform,
custom_attachment_root: Option<&str>,
) -> Result<AttachmentDiagnostic, TableError>
pub fn run_diagnostic( db: &Connection, db_path: &Path, platform: &Platform, custom_attachment_root: Option<&str>, ) -> Result<AttachmentDiagnostic, TableError>
Compute diagnostic data for the attachment table.
Counts the number of attachments that are missing, either because the path is missing from the table or the path does not point to a file.
§Example:
use imessage_database::util::{dirs::default_db_path, platform::Platform};
use imessage_database::tables::table::get_connection;
use imessage_database::tables::attachment::Attachment;
let db_path = default_db_path();
let conn = get_connection(&db_path).unwrap();
Attachment::run_diagnostic(&conn, &db_path, &Platform::macOS, None);db_path is the path to the root of the backup directory.
This is the same path used by get_connection().
Sourcepub fn get_sticker_source(&self, db: &Connection) -> Option<StickerSource>
pub fn get_sticker_source(&self, db: &Connection) -> Option<StickerSource>
Parse a sticker’s source from the bundle ID in STICKER_USER_INFO.
Calling this reads a BLOB from the database.
Sourcepub fn get_sticker_source_application_name(
&self,
db: &Connection,
) -> Option<String>
pub fn get_sticker_source_application_name( &self, db: &Connection, ) -> Option<String>
Parse a sticker’s source application name from ATTRIBUTION_INFO.
Calling this reads a BLOB from the database.
Sourcepub fn get_sticker_decoration(
&self,
db: &Connection,
platform: &Platform,
db_path: &Path,
attachment_root: Option<&str>,
) -> Option<StickerDecoration>
pub fn get_sticker_decoration( &self, db: &Connection, platform: &Platform, db_path: &Path, attachment_root: Option<&str>, ) -> Option<StickerDecoration>
Resolve a sticker’s StickerSource into a StickerDecoration.
Combines get_sticker_source,
get_sticker_source_application_name,
and get_sticker_effect so
consumers don’t have to re-derive the dispatch.
Returns None in three cases:
- The sticker has no readable source (missing
STICKER_USER_INFO, malformed plist, or unrecognized bundle id). - The source is
StickerSource::Genmojibutemoji_descriptionis unset. - The source is
StickerSource::UserGeneratedbut the effect blob is missing or unreadable.
StickerSource::Memoji and StickerSource::App always yield
Some.
Trait Implementations§
Source§impl Debug for Attachment
impl Debug for Attachment
Source§impl Table for Attachment
impl Table for Attachment
Source§fn from_row(row: &Row<'_>) -> Result<Attachment>
fn from_row(row: &Row<'_>) -> Result<Attachment>
Self. Returns rusqlite::Result
for direct use inside rusqlite::query_map / query_row
callbacks. For high-level iteration, prefer Table::rows or
Table::row.Source§fn get(db: &Connection) -> Result<CachedStatement<'_>, TableError>
fn get(db: &Connection) -> Result<CachedStatement<'_>, TableError>
SELECT * statement.Source§fn rows<'stmt, P: Params>(
stmt: &'stmt mut Statement<'_>,
params: P,
) -> Result<impl Iterator<Item = Result<Self, TableError>> + 'stmt, TableError>where
Self: 'stmt,
fn rows<'stmt, P: Params>(
stmt: &'stmt mut Statement<'_>,
params: P,
) -> Result<impl Iterator<Item = Result<Self, TableError>> + 'stmt, TableError>where
Self: 'stmt,
stmt, deserializing each via
from_row. Errors at row-fetch or row-deserialize
time are surfaced uniformly as TableError. Accepts both
rusqlite::Statement and rusqlite::CachedStatement (the
latter via deref coercion). Read moreSource§fn row<P: Params>(
stmt: &mut Statement<'_>,
params: P,
) -> Result<Self, TableError>
fn row<P: Params>( stmt: &mut Statement<'_>, params: P, ) -> Result<Self, TableError>
stmt. Returns
TableError::QueryError if the row is missing or fails to
deserialize. Accepts both rusqlite::Statement and
rusqlite::CachedStatement (the latter via deref coercion).Source§fn stream<F, E>(db: &Connection, callback: F) -> Result<(), E>
fn stream<F, E>(db: &Connection, callback: F) -> Result<(), E>
SELECT * query using a
callback. Builds and discards the prepared statement internally, so
the caller never sees it. Read more