Skip to content

Commit ef68770

Browse files
committed
structure plugin to use local lib
1 parent fda2ec5 commit ef68770

File tree

4 files changed

+168
-154
lines changed

4 files changed

+168
-154
lines changed

main.py

Lines changed: 8 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,14 @@
11
# -*- coding: utf-8 -*-
2-
import os.path
3-
import json
4-
from configparser import ConfigParser
2+
import sys
3+
import os
54

6-
import requests
75

8-
try:
9-
from wox import Wox as FlowLauncher
10-
from wox import WoxAPI as API
11-
PRETEXT = 'Wox'
12-
except ModuleNotFoundError:
13-
from flowlauncher import FlowLauncher
14-
from flowlauncher import FlowLauncherAPI as API
15-
PRETEXT = 'Flow.Launcher'
6+
parent_folder_path = os.path.abspath(os.path.dirname(__file__))
7+
sys.path.append(parent_folder_path)
8+
sys.path.append(os.path.join(parent_folder_path, 'lib'))
9+
sys.path.append(os.path.join(parent_folder_path, 'plugin'))
1610

17-
PLUGIN_JSON = './plugin.json'
18-
SETTINGS = '../../Settings/Settings.json'
19-
CONFIG_FILE = './config.ini'
20-
DEV_CONFIG = './.dev-config.ini'
21-
ICONS_FOLDER = './icons/icons_white/'
22-
MAX_ITEMS = 30
23-
24-
class Commander(FlowLauncher):
25-
26-
def __init__(self):
27-
self.results = []
28-
self.load_config()
29-
if self.ssl:
30-
self.protocol = "http://"
31-
else:
32-
self.protocol = "https://"
33-
self.url = f"{self.protocol}{self.host}:{self.port}/"
34-
self.headers = {
35-
"Authorization": f"Bearer {self.token}",
36-
"content-type": "application/json",
37-
}
38-
self.session = requests.Session()
39-
self.settings()
40-
super().__init__()
41-
42-
def load_config(self):
43-
config = ConfigParser()
44-
config_file = CONFIG_FILE
45-
if os.path.exists(DEV_CONFIG):
46-
config_file = DEV_CONFIG
47-
config.read(config_file)
48-
_section = config.sections()[0]
49-
self.host = config[_section]['host']
50-
self.port = config[_section]['port']
51-
self.token = config[_section]['token']
52-
self.ssl = config[_section]['ssl']
53-
self.verify_ssl = config[_section]['verify_ssl']
54-
55-
def settings(self):
56-
with open(PLUGIN_JSON, 'r') as f:
57-
self.id = json.load(f)['ID']
58-
with open(SETTINGS, 'r') as f:
59-
self.settings = json.load(f)
60-
self.keyword = self.settings['PluginSettings']['Plugins'][self.id]['ActionKeywords'][0]
61-
62-
def request(self, method, endpoint, data=None):
63-
url = f"{self.url}api/{endpoint}"
64-
if data:
65-
data = json.dumps(data)
66-
response = self.session.request(method, url, headers=self.headers, data=data, verify=self.verify_ssl)
67-
response.raise_for_status()
68-
return response.json()
69-
70-
def states(self):
71-
return self.request('GET', 'states')
72-
73-
def entity_state(self, entity_id):
74-
endpoint = f"states/{entity_id}"
75-
return self.request('GET', endpoint)
76-
77-
def services(self, domain, service, data):
78-
endpoint = f"services/{domain}/{service}"
79-
return self.request('POST', endpoint, data)
80-
81-
def toggle(self, entity_id):
82-
data = {
83-
"entity_id": entity_id
84-
}
85-
# Locks CANNOT be toggle with homeassistant domain
86-
if entity_id.startswith("lock"):
87-
lock_state = self.entity_state(entity_id)['state']
88-
if lock_state == "locked":
89-
self.services("lock", "unlock", {"entity_id": entity_id})
90-
else:
91-
self.services("lock", "lock", {"entity_id": entity_id})
92-
else:
93-
self.services('homeassistant', 'toggle', data=data)
94-
95-
def play_pause(self, entity_id):
96-
data = {
97-
"entity_id": entity_id
98-
}
99-
self.services('media_player', 'media_play_pause', data=data)
100-
101-
def context_menu(self, data):
102-
results = []
103-
results.append({
104-
"Title": data,
105-
"SubTitle": "test",
106-
#"IcoPath":ico,
107-
"JsonRPCAction": {
108-
#change query to show only service type
109-
"method": "Wox.ChangeQuery",
110-
"parameters": ["ha", False],
111-
# hide the query wox or not
112-
"dontHideAfterAction": True
113-
}
114-
})
115-
return results
116-
117-
def query(self, query):
118-
q = query.lower()
119-
states = self.states()
120-
for entity in states:
121-
friendly_name = entity['attributes'].get('friendly_name', '')
122-
entity_id = entity['entity_id']
123-
domain = entity_id.split('.')[0]
124-
state = entity['state']
125-
icon_string = f"{domain}_{state}"
126-
icon = f"{ICONS_FOLDER}{domain}.png"
127-
if os.path.exists(f"{ICONS_FOLDER}{icon_string}.png"):
128-
icon = f"{ICONS_FOLDER}{icon_string}.png"
129-
if q in entity_id.lower() or q in friendly_name.lower():
130-
self.results.append({
131-
"Title": f"{friendly_name or entity_id}",
132-
"SubTitle": f"[{domain}] {state}",
133-
"IcoPath": icon,
134-
"JsonRPCAction": {
135-
"method": "action",
136-
"parameters": [entity_id],
137-
"dontHideAfterAction": False
138-
}
139-
})
140-
if len(self.results) > MAX_ITEMS:
141-
break
142-
143-
144-
if len(self.results) == 0:
145-
self.results.append({
146-
"Title": "No Results Found!",
147-
"SubTitle": "",
148-
"IcoPath": f"{ICONS_FOLDER}light_off.png",
149-
})
150-
return self.results
151-
152-
def action(self, entity_id):
153-
API.start_loadingbar()
154-
if entity_id.startswith("media_player."):
155-
self.play_pause(entity_id)
156-
else:
157-
self.toggle(entity_id)
11+
from plugin.main import Commander
15812

15913
if __name__ == "__main__":
160-
Commander()
14+
Commander()

plugin/__init__.py

Whitespace-only changes.
File renamed without changes.

plugin/main.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# -*- coding: utf-8 -*-
2+
import os.path
3+
import json
4+
from configparser import ConfigParser
5+
6+
import requests
7+
8+
try:
9+
from wox import Wox as FlowLauncher
10+
from wox import WoxAPI as API
11+
PRETEXT = 'Wox'
12+
except ModuleNotFoundError:
13+
from flowlauncher import FlowLauncher
14+
from flowlauncher import FlowLauncherAPI as API
15+
PRETEXT = 'Flow.Launcher'
16+
17+
PLUGIN_JSON = './plugin.json'
18+
SETTINGS = '../../Settings/Settings.json'
19+
CONFIG_FILE = './plugin/config.ini'
20+
DEV_CONFIG = './plugin/.dev-config.ini'
21+
ICONS_FOLDER = './icons/icons_white/'
22+
MAX_ITEMS = 30
23+
24+
class Commander(FlowLauncher):
25+
26+
def __init__(self):
27+
self.results = []
28+
self.load_config()
29+
if self.ssl:
30+
self.protocol = "http://"
31+
else:
32+
self.protocol = "https://"
33+
self.url = f"{self.protocol}{self.host}:{self.port}/"
34+
self.headers = {
35+
"Authorization": f"Bearer {self.token}",
36+
"content-type": "application/json",
37+
}
38+
self.session = requests.Session()
39+
self.settings()
40+
super().__init__()
41+
42+
def load_config(self):
43+
config = ConfigParser()
44+
config_file = CONFIG_FILE
45+
if os.path.exists(DEV_CONFIG):
46+
config_file = DEV_CONFIG
47+
config.read(config_file)
48+
_section = config.sections()[0]
49+
self.host = config[_section]['host']
50+
self.port = config[_section]['port']
51+
self.token = config[_section]['token']
52+
self.ssl = config[_section]['ssl']
53+
self.verify_ssl = config[_section]['verify_ssl']
54+
55+
def settings(self):
56+
with open(PLUGIN_JSON, 'r') as f:
57+
self.id = json.load(f)['ID']
58+
with open(SETTINGS, 'r') as f:
59+
self.settings = json.load(f)
60+
self.keyword = self.settings['PluginSettings']['Plugins'][self.id]['ActionKeywords'][0]
61+
62+
def request(self, method, endpoint, data=None):
63+
url = f"{self.url}api/{endpoint}"
64+
if data:
65+
data = json.dumps(data)
66+
response = self.session.request(method, url, headers=self.headers, data=data, verify=self.verify_ssl)
67+
response.raise_for_status()
68+
return response.json()
69+
70+
def states(self):
71+
return self.request('GET', 'states')
72+
73+
def entity_state(self, entity_id):
74+
endpoint = f"states/{entity_id}"
75+
return self.request('GET', endpoint)
76+
77+
def services(self, domain, service, data):
78+
endpoint = f"services/{domain}/{service}"
79+
return self.request('POST', endpoint, data)
80+
81+
def toggle(self, entity_id):
82+
data = {
83+
"entity_id": entity_id
84+
}
85+
# Locks CANNOT be toggle with homeassistant domain
86+
if entity_id.startswith("lock"):
87+
lock_state = self.entity_state(entity_id)['state']
88+
if lock_state == "locked":
89+
self.services("lock", "unlock", {"entity_id": entity_id})
90+
else:
91+
self.services("lock", "lock", {"entity_id": entity_id})
92+
else:
93+
self.services('homeassistant', 'toggle', data=data)
94+
95+
def play_pause(self, entity_id):
96+
data = {
97+
"entity_id": entity_id
98+
}
99+
self.services('media_player', 'media_play_pause', data=data)
100+
101+
def context_menu(self, data):
102+
results = []
103+
results.append({
104+
"Title": data,
105+
"SubTitle": "test",
106+
#"IcoPath":ico,
107+
"JsonRPCAction": {
108+
#change query to show only service type
109+
"method": "Wox.ChangeQuery",
110+
"parameters": ["ha", False],
111+
# hide the query wox or not
112+
"dontHideAfterAction": True
113+
}
114+
})
115+
return results
116+
117+
def query(self, query):
118+
q = query.lower()
119+
states = self.states()
120+
for entity in states:
121+
friendly_name = entity['attributes'].get('friendly_name', '')
122+
entity_id = entity['entity_id']
123+
domain = entity_id.split('.')[0]
124+
state = entity['state']
125+
icon_string = f"{domain}_{state}"
126+
icon = f"{ICONS_FOLDER}{domain}.png"
127+
if os.path.exists(f"{ICONS_FOLDER}{icon_string}.png"):
128+
icon = f"{ICONS_FOLDER}{icon_string}.png"
129+
if q in entity_id.lower() or q in friendly_name.lower():
130+
self.results.append({
131+
"Title": f"{friendly_name or entity_id}",
132+
"SubTitle": f"[{domain}] {state}",
133+
"IcoPath": icon,
134+
"JsonRPCAction": {
135+
"method": "action",
136+
"parameters": [entity_id],
137+
"dontHideAfterAction": False
138+
}
139+
})
140+
if len(self.results) > MAX_ITEMS:
141+
break
142+
143+
144+
if len(self.results) == 0:
145+
self.results.append({
146+
"Title": "No Results Found!",
147+
"SubTitle": "",
148+
"IcoPath": f"{ICONS_FOLDER}light_off.png",
149+
})
150+
return self.results
151+
152+
def action(self, entity_id):
153+
API.start_loadingbar()
154+
if entity_id.startswith("media_player."):
155+
self.play_pause(entity_id)
156+
else:
157+
self.toggle(entity_id)
158+
159+
if __name__ == "__main__":
160+
Commander()

0 commit comments

Comments
 (0)