translator.py 6.04 KB
Newer Older
1
2
3
import llfuse
import os
import sqlfuse
4
import threading
Gerion Entrup's avatar
Gerion Entrup committed
5

6
from mbdata.models import Recording, Release, ReleaseGroup, Track, Artist, ArtistCredit, ArtistCreditName, Medium
7
from sqlalchemy import distinct
8
9
from sqlalchemy.sql import select, join
from sqlfuse import QPath, FPath, Where, Functions
Gerion Entrup's avatar
Gerion Entrup committed
10

11
class Translator(threading.Thread):
12
13
14
    """
    Manages the mapping between filesystem and database.
    """
15
16
17
    def __init__(self, session_fac, mountpoint):
        super().__init__(target=self)
        self._session = session_fac()
18
19
        self._filesystem = sqlfuse.init(self._session, self._create_fs())
        self._mountpoint = mountpoint
Gerion Entrup's avatar
Gerion Entrup committed
20

21
    def _create_fs(self):
22
23
24
25
26
27
28
29
30
        fs = [QPath("/Recordings/<recording>",
                    select([Recording.name, Recording.gid, Recording.ftype, Recording.path, ArtistCredit.name]).select_from(join(Recording, ArtistCredit)),
                    Functions(ArtistCredit.name, ' - ', Recording.name, '.', Recording.ftype)),
              #FPath("/Recordings/<and>", Translator._and, is_dir=True),
              #FPath("/Recordings/<or>", Translator._or, is_dir=True),
              QPath("/Artists/<artist>", select([Artist.name, Artist.gid]), Functions(Artist.name)),
              QPath("/Artists/<artist>/Recordings/<recording>",
                    select([Recording.name, Recording.gid, Recording.ftype, Recording.path]).select_from(join(join(join(Recording, ArtistCredit), ArtistCreditName), Artist)),
                    Functions(Recording.name, '.', Recording.ftype),
31
                    where=[Where(Artist.gid.__eq__, "<artist>", "artist_gid")]),
32
33
              #("/Artists/<artist>/Recordings/<and>", _and),
              #("/Artists/<artist>/Recordings/<or>", _or),
34
35
36
37
38
39
40
41
42
43
44
              QPath("/Artists/<artist>/<releasegroup>",
                    select([ReleaseGroup.name, ReleaseGroup.id]).select_from(join(join(join(ReleaseGroup, ArtistCredit), ArtistCreditName), Artist)),
                    Functions(ReleaseGroup.name),
                    where=[Where(Artist.gid.__eq__, "<artist>", "artist_gid")]),
              QPath("/Artists/<artist>/<releasegroup>/<release>",
                    select([Release.name, Release.gid, Release.release_group_id]),
                    Functions(Release.name, '.', Release.gid),
                    where=[Where(Release.release_group_id.__eq__, '<releasegroup>', 'release_group_id')]),
              QPath("/Artists/<artist>/<releasegroup>/<release>/<track>",
                    select([Track.name, Track.number, Recording.gid, Recording.path, Recording.ftype]).select_from(join(join(join(Track, Recording), Medium), Release)),
                    Functions(Track.number, ' ', Track.name, '.', Recording.ftype),
45
                    where=[Where(Release.gid.__eq__, '<release>', 'release_gid')]),
46
47
              #("/Artists/<artist>/<releasegroup>/<release>/<and>", _and),
              #("/Artists/<artist>/<releasegroup>/<release>/<or>", _or),
48
              #QPath("/Artists/<artist>/Works/<work>"
49
50
51
              #("/Artists/<artist>/Works/<work>/<recording>"
              #("/Artists/<artist>/Works/<work>/<and>", _and),
              #("/Artists/<artist>/Works/<work>/<or>", _or),
52
53
54
55
56
57
58
59
60
61
62
              QPath("/Releases/<releasegroup>",
                    select([ReleaseGroup.name, ReleaseGroup.id]),
                    Functions(ReleaseGroup.name)),
              QPath("/Releases/<releasegroup>/<release>",
                    select([Release.name, Release.gid, Release.release_group_id]),
                    Functions(Release.name, '.', Release.gid),
                    where=[Where(Release.release_group_id.__eq__, '<releasegroup>', 'release_group_id')]),
              QPath("/Releases/<releasegroup>/<release>/<track>",
                    select([Track.name, Track.number, Recording.gid, Recording.path, Recording.ftype]).select_from(join(join(join(Track, Recording), Medium), Release)),
                    Functions(Track.number, ' ', Track.name, '.', Recording.ftype),
                    where=[Where(Release.gid.__eq__, '<release>', 'release_gid')])]
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
              #("/Releases/<releasegroup>/<release>/<and>", _and),
              #("/Releases/<releasegroup>/<release>/<or>", _or),
              #("/Works"
              #("/Works/<work>"
              #("/Works/<work>/<recording>"
              #("/Works/<work>/<and>", _and),
              #("/Works/<work>/<or>", _or),
              #("/Year/"
              #("/Year/After/"
              #("/Year/After/<year>"
              #("/Year/After/<year>/<recording>"
              #("/Year/After/<year>/<and>", _and),
              #("/Year/After/<year>/<or>", _or),
              #("/Year/Before/"
              #("/Year/Before/<year>"
              #("/Year/Before/<year>/<recording>"
              #("/Year/Before/<year>/<and>", _and),
              #("/Year/Before/<year>/<or>", _or),
              #("/Year/Between/"
              #("/Year/Between/<year> and"
              #("/Year/Between/<year> and/<year>"
              #("/Year/Between/<year> and/<year>/<recording>"
              #("/Year/Between/<year> and/<year>/<and>", _and),
              #("/Year/Between/<year> and/<year>/<or>", _or),
              #("/Year/<year>"
              #("/Playlists/<name>"
              #("/Playlists/<name>/<recording>"
              #("/Playlists/<name>/<and>", _and),
              #("/Playlists/<name>/<or>", _or),
              #("/RecordingsAsLink/<recording>", _recording_link),
              #("/settings.txt", _settings),
94
              #FPath("/log.txt", Translator._log, is_dir=False)]
95
96
97
98
99
        return fs

    def _result_to_string(result):
        return result.name

100
101
102
    def run(self):
        self.mount(self._mountpoint)

Gerion Entrup's avatar
Gerion Entrup committed
103
    def mount(self, mountpoint):
104
105
106
107
108
109
110
111
112
113
114
115
116
        # from utils import debug_breakpoint
        # debug_breakpoint()
        fuse_options = set(llfuse.default_options)
        fuse_options.add('fsname=brainzfs')
        llfuse.init(self._filesystem, self._mountpoint, fuse_options)
        try:
            llfuse.main(workers=1)
        except:
            llfuse.close(unmount=False)
            raise

        llfuse.close()
        # TODO fix
117
118
        self._session.commit()
        self._session.close()
Gerion Entrup's avatar
Gerion Entrup committed
119