|
1 | 1 | import webbrowser |
2 | 2 | from pathlib import Path |
3 | | -from difflib import SequenceMatcher as SM |
4 | 3 |
|
5 | | -from flox import Flox, ICON_SETTINGS |
6 | | -import playnite as pn |
| 4 | +from flox import Flox |
| 5 | +from playnite import DEFAULT_PLAYNITE_DIR, PlayniteApp |
| 6 | +from result import Result, OpenInPlaynite, LaunchGameContext |
| 7 | +from filters import IsInstalled, IsHidden |
| 8 | +from exceptions import PlayniteNotFound, LibraryNotFound |
7 | 9 |
|
8 | | - |
9 | | -SOURCE_FILTER = '#' |
10 | | -INSTALL_FILTER = '@' |
11 | | -HIDDEN_FILTER = '!' |
12 | | -SCORE_CUTOFF = 10 |
13 | 10 | PLUGIN_URI = 'playnite://playnite/installaddon/FlowLauncherExporter' |
14 | 11 |
|
15 | | -def match(query, text): |
16 | | - return int(SM( |
17 | | - lambda x: x == " ", |
18 | | - query, |
19 | | - text.lower()).ratio() * 100 |
20 | | - ) |
21 | | - |
22 | 12 | class Playnite(Flox): |
23 | 13 |
|
24 | 14 | def load_settings(self): |
25 | | - self.playnite_path = self.settings.setdefault('playnite_path', str(pn.DATA_FOLDER)) |
| 15 | + self.applied_filters = [] |
| 16 | + self.playnite_path = self.settings.setdefault('playnite_path', str(DEFAULT_PLAYNITE_DIR)) |
26 | 17 | self.hide_uninstalled = self.settings.get('hide_uninstalled', True) |
27 | | - |
28 | | - def missing_library(self): |
29 | | - self.add_item( |
30 | | - title='Library file not found!', |
31 | | - subtitle="Please set the path to Playnite\'s data directory in settings.", |
32 | | - icon=ICON_SETTINGS, |
33 | | - method=self.open_setting_dialog |
34 | | - ) |
35 | | - self.add_item( |
36 | | - title='Install FlowLauncherExporter plugin.', |
37 | | - subtitle='FlowLauncherExporter plugin is required to use this plugin.', |
38 | | - icon='', |
39 | | - method=self.uri, |
40 | | - parameters=[PLUGIN_URI] |
41 | | - |
42 | | - ) |
43 | | - |
44 | | - def main_search(self, query): |
45 | | - for game in self.games: |
46 | | - score = match(query, game.name) |
47 | | - if score >= SCORE_CUTOFF or query == '': |
48 | | - if game.is_installed: |
49 | | - subtitle = game.install_directory |
50 | | - uri = game.start_uri |
51 | | - else: |
52 | | - subtitle = 'Not Installed' |
53 | | - uri = game.show_uri |
54 | | - self.add_item( |
55 | | - title=game.name, |
56 | | - subtitle=f'{game.source["Name"]}: {subtitle}', |
57 | | - icon=str(game.icon_path), |
58 | | - method=self.uri, |
59 | | - parameters=[uri], |
60 | | - context=[game.show_uri], |
61 | | - score=score |
62 | | - ) |
63 | | - |
64 | | - def source_filter(self, query): |
65 | | - sources = [game.source['Name'] for game in self.games] |
66 | | - sources = set(sources) |
67 | | - for source in sources: |
68 | | - if source.lower() in query: |
69 | | - query = query.replace(source.lower(), '').lstrip() |
70 | | - self.games = [game for game in self.games if source.lower() == game.source['Name'].lower()] |
71 | | - break |
72 | | - if query in source.lower() or query == '': |
73 | | - _ = self.add_item( |
74 | | - title=f'{SOURCE_FILTER}{source}', |
75 | | - subtitle='Filter by source.', |
76 | | - icon='', |
77 | | - method=self.change_query, |
78 | | - dont_hide=True, |
79 | | - ) |
80 | | - _['JsonRPCAction']['Parameters'] = [f"{_['AutoCompleteText']} "] |
81 | | - else: |
82 | | - self.games = [] |
83 | | - return query |
84 | | - |
85 | | - def install_filter(self): |
86 | | - self.games = [game for game in self.games if not game.is_installed] |
87 | | - |
88 | | - def uninstalled_filter(self): |
89 | | - self.games = [game for game in self.games if game.is_installed and (game.install_directory != None or game.install_directory != "")] |
90 | | - |
91 | | - def remove_hidden(self): |
92 | | - self.games = [game for game in self.games if not game.hidden] |
| 18 | + if self.hide_uninstalled: |
| 19 | + self.applied_filters.append(IsInstalled) |
| 20 | + # If has "Show Hidden" setting, hide hidden games |
| 21 | + if not self.settings.get('show_hidden', False): |
| 22 | + self.applied_filters.append(IsHidden(invert=True)) |
| 23 | + self.pn = PlayniteApp(self.playnite_path) |
93 | 24 |
|
94 | 25 | def query(self, query): |
95 | | - self.load_settings() |
96 | | - query = query.lower() |
97 | 26 | try: |
98 | | - self.games = pn.import_games(self.playnite_path) |
99 | | - except FileNotFoundError: |
100 | | - self.missing_library() |
101 | | - return |
102 | | - if query.startswith(SOURCE_FILTER): |
103 | | - query = query[len(SOURCE_FILTER):] |
104 | | - query = self.source_filter(query) |
105 | | - if INSTALL_FILTER in query: |
106 | | - query = query.replace(INSTALL_FILTER, '') |
107 | | - self.install_filter() |
108 | | - elif self.hide_uninstalled: |
109 | | - self.uninstalled_filter() |
110 | | - if HIDDEN_FILTER not in query: |
111 | | - self.remove_hidden() |
112 | | - else: |
113 | | - query = query.replace(HIDDEN_FILTER, '') |
114 | | - self.main_search(query) |
115 | | - |
| 27 | + self.load_settings() |
| 28 | + games = self.pn.search(query, self.applied_filters) |
| 29 | + for game in games: |
| 30 | + self.add_item( |
| 31 | + **Result(game).to_dict() |
| 32 | + ) |
| 33 | + except PlayniteNotFound: |
| 34 | + self.add_item( |
| 35 | + title='Playnite not found! Set the path in the settings.', |
| 36 | + subtitle='Open settings.', |
| 37 | + method=self.open_setting_dialog |
| 38 | + ) |
| 39 | + except LibraryNotFound: |
| 40 | + self.add_item( |
| 41 | + title='Flow Launcher Exporter not found! Install it in Playnite.', |
| 42 | + subtitle='Click to install now.', |
| 43 | + method=self.uri, |
| 44 | + parameters=[PLUGIN_URI] |
| 45 | + ) |
116 | 46 |
|
117 | 47 | def context_menu(self, data): |
118 | | - show_uri = data[0] |
119 | | - icon = str(self.icon if Path(self.icon).is_absolute() else Path(self.plugindir, self.icon)) |
120 | | - self.logger.warning(icon) |
121 | | - self.add_item( |
122 | | - title='Open in Playnite', |
123 | | - subtitle='Shows Game in Playnite library.', |
124 | | - icon=icon, |
125 | | - method=self.uri, |
126 | | - parameters=[show_uri], |
127 | | - ) |
| 48 | + self.load_settings() |
| 49 | + game = self.pn.game(data) |
| 50 | + if game: |
| 51 | + self.add_item(**OpenInPlaynite(game).to_dict()) |
| 52 | + self.add_item(**LaunchGameContext(game).to_dict()) |
128 | 53 |
|
129 | 54 | def uri(self, uri): |
130 | 55 | webbrowser.open(uri) |
|
0 commit comments