Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

my.telegram: initial module #270

Merged
merged 3 commits into from
Feb 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions my/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,10 @@ class export:
export_path: Paths = ''
class active_browser:
export_path: Paths = ''


class telegram:
class telegram_backup:
export_path: PathIsh = ''


2 changes: 2 additions & 0 deletions my/core/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def sqlite_connection(db: PathIsh, *, immutable: bool=False, row_factory: Option
dbp = f'file:{db}'
# https://www.sqlite.org/draft/uri.html#uriimmutable
if immutable:
# assert results in nicer error than sqlite3.OperationalError
assert Path(db).exists(), db
dbp = f'{dbp}?immutable=1'
row_factory_: Any = None
if row_factory is not None:
Expand Down
77 changes: 77 additions & 0 deletions my/telegram/telegram_backup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""
Telegram data via [fabianonline/telegram_backup](https://github.com/fabianonline/telegram_backup) tool
"""

from dataclasses import dataclass
from datetime import datetime, timezone
import sqlite3
from typing import Dict, Iterator

from my.core import datetime_aware, PathIsh
from my.core.sqlite import sqlite_connection

from my.config import telegram as user_config


@dataclass
class config(user_config.telegram_backup):
# path to the export database.sqlite
export_path: PathIsh


@dataclass
class Chat:
id: str
name: str
# not sure if need type?


@dataclass
class User:
id: str
name: str


@dataclass
class Message:
id: int
time: datetime_aware
chat: Chat
sender: User
text: str


Chats = Dict[str, Chat]
def _message_from_row(r: sqlite3.Row, *, chats: Chats) -> Message:
ts = r['time']
time = datetime.fromtimestamp(ts, tz=timezone.utc)
chat = chats[r['source_id']]
sender = chats[r['sender_id']]
return Message(
id=r['message_id'],
time=time,
chat=chat,
sender=sender,
text=r['text'],
)


def messages() -> Iterator[Message]:
with sqlite_connection(config.export_path, immutable=True, row_factory='row') as db:

chats: Chats = {}
for r in db.execute('SELECT * FROM chats'):
chat = Chat(id=r['id'], name=r['name'])
assert chat.id not in chats
chats[chat.id] = chat

for r in db.execute('SELECT * FROM users'):
chat = Chat(id=r['id'], name=f'{r["first_name"]} {r["last_name"]}')
assert chat.id not in chats
chats[chat.id] = chat

# TODO order by? not sure
for r in db.execute('SELECT * FROM messages WHERE message_type NOT IN ("service_message", "empty_message")'):
# seems like the only remaining have message_type = 'message'
yield _message_from_row(r, chats=chats)

13 changes: 9 additions & 4 deletions my/tinder/android.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@

from more_itertools import unique_everseen

from my.core import Paths, get_files, Res, assert_never, stat, Stats, datetime_aware
from my.core import Paths, get_files, Res, assert_never, stat, Stats, datetime_aware, LazyLogger
from my.core.sqlite import sqlite_connection


logger = LazyLogger(__name__)


from my.config import tinder as user_config
@dataclass
class config(user_config.android):
Expand All @@ -38,7 +41,7 @@ class _BaseMatch:
id: str


@dataclass
@dataclass(unsafe_hash=True)
class _Match(_BaseMatch):
person_id: str

Expand All @@ -58,7 +61,7 @@ class _BaseMessage:
text: str


@dataclass
@dataclass(unsafe_hash=True)
class _Message(_BaseMessage):
match_id: str
from_id: str
Expand All @@ -83,7 +86,9 @@ def inputs() -> Sequence[Path]:


def _entities() -> Iterator[Res[_Entity]]:
for db_file in inputs():
dbs = inputs()
for i, db_file in enumerate(dbs):
logger.debug(f'processing {db_file} {i}/{len(dbs)}')
with sqlite_connection(db_file, immutable=True, row_factory='row') as db:
yield from _handle_db(db)

Expand Down