tinder.android: infer user's own name automatically

This commit is contained in:
Dima Gerasimov 2023-10-23 19:43:54 +01:00 committed by karlicoss
parent f355a55e06
commit 414b88178f

View file

@ -3,7 +3,7 @@ Tinder data from Android app database (in =/data/data/com.tinder/databases/tinde
"""
from __future__ import annotations
from collections import defaultdict
from collections import defaultdict, Counter
from dataclasses import dataclass
from datetime import datetime, timezone
from itertools import chain
@ -13,16 +13,17 @@ from typing import Sequence, Iterator, Union, Dict, List, Mapping
from more_itertools import unique_everseen
from my.core import Paths, get_files, Res, assert_never, stat, Stats, datetime_aware, LazyLogger
from my.core import Paths, get_files, Res, assert_never, stat, Stats, datetime_aware, make_logger
from my.core.error import echain
from my.core.sqlite import sqlite_connection
import my.config
logger = LazyLogger(__name__)
logger = make_logger(__name__)
from my.config import tinder as user_config
@dataclass
class config(user_config.android):
class config(my.config.tinder.android):
# paths[s]/glob to the exported sqlite databases
export_path: Paths
@ -88,15 +89,24 @@ Entity = Union[Person, Match, Message]
def _entities() -> Iterator[Res[_Entity]]:
dbs = inputs()
for i, db_file in enumerate(dbs):
logger.debug(f'processing {db_file} {i}/{len(dbs)}')
logger.info(f'processing {db_file} {i}/{len(dbs)}')
with sqlite_connection(db_file, immutable=True, row_factory='row') as db:
yield from _handle_db(db)
def _handle_db(db: sqlite3.Connection) -> Iterator[Res[_Entity]]:
# profile_user_view contains our own user id
user_profile_rows = list(db.execute('SELECT * FROM profile_user_view'))
if len(user_profile_rows) == 0:
# shit, sometime in 2023 profile_user_view stoppped containing user profile..
# presumably the most common from_id/to_id would be our own username
counter = Counter([id_ for (id_,) in db.execute('SELECT from_id FROM message UNION ALL SELECT to_id FROM message')])
[(you_id, _)] = counter.most_common(1)
yield Person(id=you_id, name='you')
for row in chain(
db.execute('SELECT * FROM profile_user_view'),
user_profile_rows,
db.execute('SELECT * FROM match_person'),
):
try:
@ -178,7 +188,7 @@ def entities() -> Iterator[Res[Entity]]:
from_ = id2person[x.from_id]
to = id2person[x.to_id]
except Exception as e:
yield e
yield echain(RuntimeError(f'while processing {x}'), e)
continue
yield Message(
sent=x.sent,
@ -219,6 +229,8 @@ def match2messages() -> Iterator[Res[Mapping[Match, Sequence[Message]]]]:
ml.append(x)
continue
yield res
# TODO maybe a more natural return type is Iterator[Res[Tuple[Key, Value]]]
# but this doesn't work straight away because the key might have no corresponding values