Source code for plaso.parsers.sqlite_plugins.ios_twitter

# -*- coding:utf-8 -*-
"""SQLite parser plugin for Twitter on iOS 8+ database files."""

from dfdatetime import posix_time as dfdatetime_posix_time

from plaso.containers import events
from plaso.parsers import sqlite
from plaso.parsers.sqlite_plugins import interface


[docs] class IOSTwitterContactEventData(events.EventData): """Twitter on iOS 8+ contact event data. Attributes: creation_time (dfdatetime.DateTimeValues): date and time the contact was created. description (str): description of the profile. followers_count (int): number of accounts following the contact. following_count (int): number of accounts the contact is following. following (int): 1 if the contact is following the user's account, 0 if not. location (str): location of the profile. modification_time (dfdatetime.DateTimeValues): date and time the contact was last modified. name (str): name of the profile. profile_url (str): URL of the profile picture. query (str): SQL query that was used to obtain the event data. screen_name (str): screen name. url (str): URL of the profile. """ DATA_TYPE = "ios:twitter:contact"
[docs] def __init__(self): """Initializes event data.""" super().__init__(data_type=self.DATA_TYPE) self.creation_time = None self.description = None self.followers_count = None self.following = None self.following_count = None self.location = None self.modification_time = None self.name = None self.profile_url = None self.query = None self.screen_name = None self.url = None
[docs] class IOSTwitterStatusEventData(events.EventData): """Parent class for Twitter on iOS 8+ status events. Attributes: creation_time (dfdatetime.DateTimeValues): date and time the status was created. favorite_count (int): number of times the status message has been favorited. favorited (int): value to mark status as favorite by the account. modification_time (dfdatetime.DateTimeValues): date and time the status was last modified. name (str): user's profile name. query (str): SQL query that was used to obtain the event data. retweet_count (str): number of times the status message has been retweeted. text (str): content of the status message. user_identifier (int): user identifier. """ DATA_TYPE = "ios:twitter:status"
[docs] def __init__(self): """Initializes event data.""" super().__init__(data_type=self.DATA_TYPE) self.creation_time = None self.favorite_count = None self.favorited = None self.modification_time = None self.name = None self.query = None self.retweet_count = None self.text = None self.user_identifier = None
[docs] class IOSTwitterPlugin(interface.SQLitePlugin): """SQLite parser plugin for Twitter on iOS 8+ database files. The Twitter on iOS 8+ database file is typically stored in: /private/var/mobile/Containers/Data/Application/Library/Caches/databases/ twitter.db """ NAME = "twitter_ios" DATA_FORMAT = "Twitter on iOS 8 and later SQLite database (twitter.db) file" REQUIRED_STRUCTURE = { "Users": frozenset( [ "createdDate", "updatedAt", "screenName", "name", "profileImageUrl", "location", "description", "url", "following", "followersCount", "followingCount", "id", ] ), "Statuses": frozenset( [ "date", "text", "userId", "retweetCount", "favoriteCount", "favorited", "updatedAt", ] ), } QUERIES = [ ( ( "SELECT createdDate, updatedAt, screenName, name, profileImageUrl," "location, description, url, following, followersCount, followingCount" " FROM Users" ), "_ParseContactRow", ), ( ( "SELECT Statuses.date AS date, Statuses.text AS text, Statuses.userId " "AS user_id, Users.name AS name, Statuses.retweetCount AS " "retweetCount, Statuses.favoriteCount AS favoriteCount, " "Statuses.favorited AS favorited, Statuses.updatedAt AS updatedAt " "FROM Statuses LEFT join Users ON Statuses.userId = Users.id" ), "_ParseStatusRow", ), ] SCHEMAS = [ { "Lists": ( "CREATE TABLE Lists ( 'id' INTEGER PRIMARY KEY, 'name' TEXT, " "'slug' TEXT, 'desc' TEXT, 'private' INTEGER, " "'subscriberCount' INTEGER, 'memberCount' INTEGER, 'userId' " "INTEGER, 'updatedAt' REAL )" ), "ListsShadow": ( "CREATE TABLE ListsShadow ( 'id' INTEGER PRIMARY KEY, 'name' " "TEXT, 'slug' TEXT, 'desc' TEXT, 'private' INTEGER, " "'subscriberCount' INTEGER, 'memberCount' INTEGER, 'userId' " "INTEGER, 'updatedAt' REAL )" ), "MyRetweets": ( "CREATE TABLE MyRetweets ( 'statusId' INTEGER PRIMARY KEY, " "'myRetweetId' INTEGER )" ), "Statuses": ( "CREATE TABLE Statuses ( 'id' INTEGER PRIMARY KEY, 'text' TEXT, " "'date' REAL, 'userId' INTEGER, 'inReplyToStatusId' INTEGER, " "'retweetedStatusId' INTEGER, 'geotag' BLOB, 'entities' BLOB, " "'card' BLOB, 'cardUsers' BLOB, 'primaryCardType' INTEGER, " "'cardVersion' INTEGER, 'retweetCount' INTEGER, " "'favoriteCount' INTEGER, 'favorited' INTEGER, 'updatedAt' " "REAL, 'extraScribeItem' BLOB, 'withheldScope' TEXT, " "'withheldInCountries' TEXT, 'inReplyToUsername' TEXT, " "'possiblySensitive' INTEGER, 'isPossiblySensitiveAppealable' " "INTEGER, 'isLifelineAlert' INTEGER, 'isTruncated' INTEGER, " "'previewLength' INTEGER, 'fullTextLength' INTEGER, 'lang' " "TEXT, 'supplmentalLanguage' TEXT, 'includeInProfileTimeline' " "INTEGER, 'quotedStatusId' INTEGER, 'source' TEXT )" ), "StatusesShadow": ( "CREATE TABLE StatusesShadow ( 'id' INTEGER PRIMARY KEY, 'text' " "TEXT, 'date' REAL, 'userId' INTEGER, 'inReplyToStatusId' " "INTEGER, 'retweetedStatusId' INTEGER, 'geotag' BLOB, " "'entities' BLOB, 'card' BLOB, 'cardUsers' BLOB, " "'primaryCardType' INTEGER, 'cardVersion' INTEGER, " "'retweetCount' INTEGER, 'favoriteCount' INTEGER, 'favorited' " "INTEGER, 'updatedAt' REAL, 'extraScribeItem' BLOB, " "'withheldScope' TEXT, 'withheldInCountries' TEXT, " "'inReplyToUsername' TEXT, 'possiblySensitive' INTEGER, " "'isPossiblySensitiveAppealable' INTEGER, 'isLifelineAlert' " "INTEGER, 'isTruncated' INTEGER, 'previewLength' INTEGER, " "'fullTextLength' INTEGER, 'lang' TEXT, " "'supplementalLanguage' TEXT, 'includeInProfileTimeline' " "INTEGER, 'quotedStatusId' INTEGER, 'source' TEXT )" ), "Users": ( "CREATE TABLE Users ( 'id' INTEGER PRIMARY KEY, 'screenName' " "TEXT COLLATE NOCASE, 'profileImageUrl' TEXT, " "'profileBannerUrl' TEXT, 'profileLinkColorHexTriplet' INTEGER, " "'name' TEXT, 'location' TEXT, 'structuredLocation' BLOB, " "'description' TEXT, 'url' TEXT, 'urlEntities' BLOB, " "'bioEntities' BLOB, 'protected' INTEGER, 'verified' INTEGER, " "'following' INTEGER, 'deviceFollowing' INTEGER, " "'advertiserAccountType' INTEGER, 'statusesCount' INTEGER, " "'mediaCount' INTEGER, 'favoritesCount' INTEGER, " "'followingCount' INTEGER, 'followersCount' INTEGER, " "'followersCountFast' INTEGER, 'followersCountNormal' INTEGER, " "'couldBeStale' INTEGER, 'isLifelineInstitution' INTEGER, " "'hasCollections' INTEGER, 'updatedAt' REAL, 'createdDate' " "REAL, 'isTranslator' INTEGER, 'hasExtendedProfileFields' " "INTEGER, 'extendedProfileFields' BLOB, 'pinnedTweetId' " "INTEGER, 'businessProfileState' INTEGER, 'analyticsType' " "INTEGER )" ), "UsersShadow": ( "CREATE TABLE UsersShadow ( 'id' INTEGER PRIMARY KEY, " "'screenName' TEXT COLLATE NOCASE, 'profileImageUrl' TEXT, " "'profileBannerUrl' TEXT, 'profileLinkColorHexTriplet' INTEGER, " "'name' TEXT, 'location' TEXT, 'structuredLocation' BLOB, " "'description' TEXT, 'url' TEXT, 'urlEntities' BLOB, " "'bioEntities' BLOB, 'protected' INTEGER, 'verified' INTEGER, " "'following' INTEGER, 'deviceFollowing' INTEGER, " "'advertiserAccountType' INTEGER, 'statusesCount' INTEGER, " "'mediaCount' INTEGER, 'favoritesCount' INTEGER, " "'followingCount' INTEGER, 'followersCount' INTEGER, " "'followersCountFast' INTEGER, 'followersCountNormal' INTEGER, " "'couldBeStale' INTEGER, 'isLifelineInstitution' INTEGER, " "'hasCollections' INTEGER, 'updatedAt' REAL, 'createdDate' " "REAL, 'isTranslator' INTEGER, 'hasExtendedProfileFields' " "INTEGER, 'extendedProfileFields' BLOB, 'pinnedTweetId' " "INTEGER, 'businessProfileState' INTEGER, 'analyticsType' " "INTEGER )" ), } ] def _GetDateTimeRowValue(self, query_hash, row, value_name): """Retrieves a date and time value from the row. Args: query_hash (int): hash of the query, that uniquely identifies the query that produced the row. row (sqlite3.Row): row. value_name (str): name of the value. Returns: dfdatetime.PosixTime: date and time value or None if not available. """ timestamp = self._GetRowValue(query_hash, row, value_name) if timestamp is None: return None # Convert the floating point value to an integer. timestamp = int(timestamp) return dfdatetime_posix_time.PosixTime(timestamp=timestamp) def _ParseContactRow(self, parser_mediator, query, row, **unused_kwargs): """Parses a contact row from the database. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfVFS. query (str): query that created the row. row (sqlite3.Row): row resulting from query. """ query_hash = hash(query) event_data = IOSTwitterContactEventData() event_data.creation_time = self._GetDateTimeRowValue( query_hash, row, "createdDate" ) event_data.description = self._GetRowValue(query_hash, row, "description") event_data.followers_count = self._GetRowValue( query_hash, row, "followersCount" ) event_data.following = self._GetRowValue(query_hash, row, "following") event_data.following_count = self._GetRowValue( query_hash, row, "followingCount" ) event_data.location = self._GetRowValue(query_hash, row, "location") event_data.modification_time = self._GetDateTimeRowValue( query_hash, row, "updatedAt" ) event_data.name = self._GetRowValue(query_hash, row, "name") event_data.profile_url = self._GetRowValue(query_hash, row, "profileImageUrl") event_data.query = query event_data.screen_name = self._GetRowValue(query_hash, row, "screenName") event_data.url = self._GetRowValue(query_hash, row, "url") parser_mediator.ProduceEventData(event_data) def _ParseStatusRow(self, parser_mediator, query, row, **unused_kwargs): """Parses a contact row from the database. Args: parser_mediator (ParserMediator): mediates interactions between parsers and other components, such as storage and dfVFS. query (str): query that created the row. row (sqlite3.Row): row resulting from query. """ query_hash = hash(query) event_data = IOSTwitterStatusEventData() event_data.creation_time = self._GetDateTimeRowValue(query_hash, row, "date") event_data.favorite_count = self._GetRowValue(query_hash, row, "favoriteCount") event_data.favorited = self._GetRowValue(query_hash, row, "favorited") event_data.modification_time = self._GetDateTimeRowValue( query_hash, row, "updatedAt" ) event_data.name = self._GetRowValue(query_hash, row, "name") event_data.query = query event_data.retweet_count = self._GetRowValue(query_hash, row, "retweetCount") event_data.text = self._GetRowValue(query_hash, row, "text") event_data.user_identifier = self._GetRowValue(query_hash, row, "user_id") parser_mediator.ProduceEventData(event_data)
sqlite.SQLiteParser.RegisterPlugin(IOSTwitterPlugin)