aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_photo_folder_videos.py
blob: 79953a12a92fb729b4db021c8bc8bb676c4214cc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"""
A video in a photo folder (a phone's clips, backed up beside its photos,
docs/MESHBAY_DESIGN.md §9.12) is probed and thumbnailed by the video enricher,
so the Photos app can show it in its album; one outside every photo folder
and every video folder is left alone, as before.
"""

import asyncio

import pytest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from meshbay_common.crypto import generate_gek
from meshbay_node.config import Config, GroupConfig, HubConfig, KeystoreConfig, NodeConfig
from meshbay_node.daemon import NodeDaemon
from meshbay_node.indexer import DirectoryIndexer
from meshbay_node.indexer.enrich import Enricher
from meshbay_node.indexer.enrich_photo import PhotoEnricher
from meshbay_node.media_cache import MediaCache
from meshbay_node.roster import Roster

from conftest import one_root

pytestmark = pytest.mark.asyncio


def _free_port() -> int:
    import socket
    with socket.socket() as s:
        s.bind(("127.0.0.1", 0))
        return s.getsockname()[1]


async def _make_daemon(tmp_path, shared, group_id):
    config = Config(
        hub=HubConfig(url="http://localhost:9999", username="testuser"),
        node=NodeConfig(quic_port=_free_port(), ui_port=_free_port()),
        groups=[GroupConfig(
            id=group_id, name="test-group", shared_dir=str(shared),
            visibility="private", quic_port=29015,
        )],
        keystore=KeystoreConfig(path=tmp_path / "keystore.enc"),
        data_dir=tmp_path / "data",
    )
    daemon = NodeDaemon(config)
    daemon._broadcast_coalesce_secs = 0.01
    daemon._media_cache = MediaCache(db_path=tmp_path / "media_cache.db")
    await daemon._media_cache.open()
    daemon._enricher = Enricher(daemon._media_cache)
    daemon._photo_enricher = PhotoEnricher(daemon._media_cache)
    daemon._roster = Roster(db_path=tmp_path / "roster.db")
    await daemon._roster.open()
    return daemon


async def test_a_video_in_a_photo_folder_goes_to_the_video_enricher(tmp_path):
    group_id = "b" * 32
    shared = tmp_path / "shared"
    (shared / "Photos" / "bob-photos").mkdir(parents=True)
    (shared / "Photos" / "bob-photos" / "clip.mp4").write_bytes(b"a clip")
    (shared / "Photos" / "bob-photos" / "shot.jpg").write_bytes(b"a photo")
    (shared / "elsewhere.mp4").write_bytes(b"not in any app folder")

    daemon = await _make_daemon(tmp_path, shared, group_id)
    video_spawned, photo_spawned = [], []
    daemon._enricher.spawn = lambda entry, path, on_done: video_spawned.append(entry.name)
    daemon._photo_enricher.spawn = lambda entry, path, on_done: photo_spawned.append(entry.name)
    try:
        await daemon._roster.set_app_directories(group_id, "photo", ["shared/Photos"], set_by="op")
        indexer = DirectoryIndexer(
            roots=one_root(shared), group_id=group_id,
            sk_node=Ed25519PrivateKey.generate(), gek=generate_gek())
        await indexer.initial_scan()
        await daemon._on_index_change(indexer)
        await asyncio.sleep(0.05)

        assert video_spawned == ["clip.mp4"]
        assert photo_spawned == ["shot.jpg"]
    finally:
        await daemon._media_cache.close()
        await daemon._roster.close()