-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path__init__.py
More file actions
122 lines (103 loc) · 4.08 KB
/
__init__.py
File metadata and controls
122 lines (103 loc) · 4.08 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# -*- coding: utf-8 -*-
# Copyright (c) 2026 Ruben Lagerwerf
import subprocess
from pathlib import Path
from albert import *
md_iid = '5.0'
md_version = '2.0.0'
md_name = 'Tailscale'
md_description = 'Manage Tailscale connections'
md_license = 'MIT'
md_url = 'https://github.com/RubenLWF/albert-plugins/tree/main/tailscale'
md_authors = ['@RubenLWF']
md_maintainers = ['@RubenLWF']
md_bin_dependencies = ["tailscale"]
class Plugin(PluginInstance, GeneratorQueryHandler):
logo_path: Path
def __init__(self):
PluginInstance.__init__(self)
GeneratorQueryHandler.__init__(self)
# Get the icon path
plugin_dir = Path(__file__).parent
self.logo_path = plugin_dir / 'logo.svg'
def defaultTrigger(self):
return 'ts '
def items(self, query):
user_input = query.query.strip().lower()
items = []
def get_tailscale_status():
try:
result = subprocess.run(
['tailscale', 'status'],
capture_output=True,
text=True
)
return result.stdout
except:
return ""
def check_logged_in(status_output):
return "Logged out" not in status_output
def check_connected(status_output):
return status_output and "Tailscale is stopped." not in status_output and len(status_output.strip()) > 0
def tailscale_up():
subprocess.Popen(
['tailscale', 'up'],
start_new_session=True
)
def tailscale_down():
subprocess.Popen(
['tailscale', 'down'],
start_new_session=True
)
# Get current Tailscale status
status_output = get_tailscale_status()
# Check if user is logged in
if not check_logged_in(status_output):
# User is not logged in - offer login option
if not user_input or 'login'.startswith(user_input):
items.append(
StandardItem(
id='tailscale-not-logged-in',
text='Tailscale not logged in',
subtext='Follow the setup instructions to log in',
icon_factory=lambda: Icon.image(str(self.logo_path)),
)
)
else:
# User is logged in, check if connected
is_connected = check_connected(status_output)
if is_connected:
if not user_input or 'down'.startswith(user_input) or 'disconnect'.startswith(user_input):
items.append(
StandardItem(
id='tailscale-down',
text='Stop Tailscale',
subtext='Disconnect from your tailnet',
icon_factory=lambda: Icon.image(str(self.logo_path)),
actions=[
Action(
'down',
'Stop',
tailscale_down
)
]
)
)
else:
if not user_input or 'up'.startswith(user_input) or 'connect'.startswith(user_input):
items.append(
StandardItem(
id='tailscale-up',
text='Start Tailscale',
subtext='Connect to your tailnet',
icon_factory=lambda: Icon.image(str(self.logo_path)),
actions=[
Action(
'up',
'Start',
tailscale_up
)
]
)
)
yield items