sublime-beau/beau.py

132 lines
3.4 KiB
Python

import json
import platform
import sublime_plugin
from threading import Thread
from http.client import responses
from sublime import load_settings, active_window
from subprocess import check_output
SETTINGS_FILE = 'Beau.sublime-settings'
SYNTAX = 'Packages/JavaScript/JSON.sublime-syntax'
is_windows = (platform.system() == 'Windows')
class InsertTextCommand(sublime_plugin.TextCommand):
def run(self, edit, text):
self.view.insert(edit, 0, text)
class BeauCommand(sublime_plugin.TextCommand):
requests = []
path = ''
active_view = None
scope = None
folders = []
def inThread(self, command, onComplete, cwd=None):
def thread(command, onComplete):
try:
proc = check_output(command, shell=is_windows, stderr=subprocess.STDOUT, cwd=cwd)
onComplete(proc)
return
except subprocess.CalledProcessError as e:
active_window().status_message('Beau Command Failed. Open the console for more info.')
print(e.output)
thread = Thread(target=thread, args=(command, onComplete))
thread.start()
return thread
def run(self, edit):
settings = load_settings(SETTINGS_FILE)
self.path = settings.get('cli_path', '')
self.active_view = active_window().active_view()
self.folders = active_window().folders()
self.scope = self.active_view.scope_name(self.active_view.sel()[0].b)
command = [self.path, 'list', '--no-format']
if self.scope.startswith('source.yaml'):
command.extend(['-c', self.active_view.file_name()])
self.inThread(
command,
self.listFetched,
cwd=self.folders[0] if len(self.folders) > 0 else None
)
def listFetched(self, list):
requests = []
self.requests[:] = []
for line in list.splitlines():
req = line.decode('utf-8').rstrip().split('\t')
method, alias, endpoint = req
requests.append([alias, endpoint])
self.requests.append(req)
active_window().show_quick_panel(requests, self.on_request_selected)
def on_request_selected(self, index):
if index == -1:
return
method, alias, endpoint = self.requests[index]
active_window().status_message('Running: ' + alias)
def handleResult(result):
response = []
for line in result.splitlines():
response.append(line.rstrip())
active_window().status_message('')
status, endpoint, headers, body = response
status = status.decode('utf-8')
endpoint = endpoint.decode('utf-8')
headers = headers.decode('utf-8')
body = body.decode('utf-8')
results_view = active_window().new_file()
results_view.set_name('Results: ' + alias)
content = method + ' ' + endpoint + '\n'
content += status + ' ' + responses[int(status)] + '\n\n'
content += 'Response Headers: \n'
content += self.autoindent(headers)
content += '\n\nResponse Body: \n'
content += self.autoindent(body)
results_view.run_command('insert_text', {'text': content})
results_view.set_scratch(True)
results_view.set_syntax_file(SYNTAX)
command = [self.path, 'request', alias, '--no-format']
if self.scope.startswith('source.yaml'):
command.extend(['-c', self.active_view.file_name()])
self.inThread(
command,
onComplete=handleResult,
cwd=self.folders[0] if len(self.folders) > 0 else None
)
def autoindent(self, obj):
if not obj.strip():
return 'Empty';
parsed = json.loads(obj)
return json.dumps(
parsed,
sort_keys=True,
indent='\t',
separators=(',', ': '),
ensure_ascii=False
)
def is_windows(self):
return platform.system() == 'Windows'