|
11 | 11 | import base64 |
12 | 12 | import argparse |
13 | 13 | import html |
| 14 | +import time |
| 15 | +import socket |
| 16 | +import subprocess |
14 | 17 | try: |
15 | 18 | import gooey |
16 | 19 | GOOEY = True |
|
52 | 55 | extensions=['extra', 'nl2br', 'sane_lists'] |
53 | 56 | ) |
54 | 57 |
|
| 58 | +ANKI_PORT = 8765 |
| 59 | + |
55 | 60 |
|
56 | 61 | def write_safe(filename, contents): |
57 | 62 | """ |
@@ -118,6 +123,66 @@ def findignore(pattern, string, ignore_spans): |
118 | 123 | ) |
119 | 124 |
|
120 | 125 |
|
| 126 | +def wait_for_port(port, host='localhost', timeout=5.0): |
| 127 | + """Wait until a port starts accepting TCP connections. |
| 128 | + Args: |
| 129 | + port (int): Port number. |
| 130 | + host (str): Host address on which the port should exist. |
| 131 | + timeout (float): In seconds. How long to wait before raising errors. |
| 132 | + Raises: |
| 133 | + TimeoutError: The port isn't accepting connection after time specified |
| 134 | + in `timeout`. |
| 135 | + """ |
| 136 | + start_time = time.perf_counter() |
| 137 | + while True: |
| 138 | + try: |
| 139 | + with socket.create_connection((host, port), timeout=timeout): |
| 140 | + break |
| 141 | + except OSError as ex: |
| 142 | + time.sleep(0.01) |
| 143 | + if time.perf_counter() - start_time >= timeout: |
| 144 | + raise TimeoutError( |
| 145 | + 'Waited too long for the port {} on host {} to' |
| 146 | + 'start accepting connections.'.format(port, host) |
| 147 | + ) from ex |
| 148 | + |
| 149 | + |
| 150 | +def load_anki(): |
| 151 | + """Attempt to load anki in the correct profile.""" |
| 152 | + try: |
| 153 | + Config.load_config() |
| 154 | + except Exception as e: |
| 155 | + print("Error when loading config:", e) |
| 156 | + print("Please open Anki before running script again.") |
| 157 | + return False |
| 158 | + if CONFIG_DATA["Path"] and CONFIG_DATA["Profile"]: |
| 159 | + print("Anki Path and Anki Profile provided.") |
| 160 | + print("Attempting to open Anki in selected profile...") |
| 161 | + subprocess.Popen( |
| 162 | + [CONFIG_DATA["Path"], "-p", CONFIG_DATA["Profile"]] |
| 163 | + ) |
| 164 | + try: |
| 165 | + wait_for_port(ANKI_PORT) |
| 166 | + except TimeoutError: |
| 167 | + print("Opened Anki, but can't connect! Is AnkiConnect working?") |
| 168 | + return False |
| 169 | + else: |
| 170 | + print("Opened and connected to Anki successfully!") |
| 171 | + return True |
| 172 | + else: |
| 173 | + print( |
| 174 | + "Must provide both Anki Path and Anki Profile", |
| 175 | + "in order to open Anki automatically" |
| 176 | + ) |
| 177 | + |
| 178 | + |
| 179 | +def main(): |
| 180 | + """Main functionality of script.""" |
| 181 | + if not os.path.exists(CONFIG_PATH): |
| 182 | + Config.update_config() |
| 183 | + App() |
| 184 | + |
| 185 | + |
121 | 186 | class AnkiConnect: |
122 | 187 | """Namespace for AnkiConnect functions.""" |
123 | 188 |
|
@@ -626,6 +691,12 @@ def update_config(): |
626 | 691 | config["Defaults"].setdefault( |
627 | 692 | "ID Comments", "True" |
628 | 693 | ) |
| 694 | + config["Defaults"].setdefault( |
| 695 | + "Anki Path", "" |
| 696 | + ) |
| 697 | + config["Defaults"].setdefault( |
| 698 | + "Anki Profile", "" |
| 699 | + ) |
629 | 700 | # Setting up Custom Regexps |
630 | 701 | config.setdefault("Custom Regexps", dict()) |
631 | 702 | for note in note_types: |
@@ -693,6 +764,8 @@ def load_config(): |
693 | 764 | CONFIG_DATA["Comment"] = config.getboolean( |
694 | 765 | "Defaults", "ID Comments" |
695 | 766 | ) |
| 767 | + CONFIG_DATA["Path"] = config["Defaults"]["Anki Path"] |
| 768 | + CONFIG_DATA["Profile"] = config["Defaults"]["Anki Profile"] |
696 | 769 | Config.config = config # Can access later if need be |
697 | 770 | print("Loaded successfully!") |
698 | 771 |
|
@@ -1408,6 +1481,13 @@ def requests_2(self): |
1408 | 1481 |
|
1409 | 1482 |
|
1410 | 1483 | if __name__ == "__main__": |
1411 | | - if not os.path.exists(CONFIG_PATH): |
1412 | | - Config.update_config() |
1413 | | - App() |
| 1484 | + print("Attempting to connect to Anki...") |
| 1485 | + try: |
| 1486 | + wait_for_port(ANKI_PORT) |
| 1487 | + except TimeoutError: |
| 1488 | + print("Couldn't connect to Anki, attempting to open Anki...") |
| 1489 | + if load_anki(): |
| 1490 | + main() |
| 1491 | + else: |
| 1492 | + print("Connected!") |
| 1493 | + main() |
0 commit comments