Added a "remote diagnostics" tool
This commit is contained in:
@@ -8,6 +8,7 @@ import socket
|
||||
import sockjs.tornado
|
||||
import subprocess
|
||||
import tornado
|
||||
from urllib.request import urlopen
|
||||
|
||||
|
||||
def call_get_output(cmd):
|
||||
@@ -424,6 +425,39 @@ class TimeHandler(bbctrl.APIHandler):
|
||||
subprocess.Popen(['timedatectl', 'set-timezone', timezone])
|
||||
|
||||
|
||||
class RemoteDiagnosticsHandler(bbctrl.APIHandler):
|
||||
|
||||
def get(self):
|
||||
code = self.get_query_argument("code", "")
|
||||
command = self.get_query_argument("command", "")
|
||||
|
||||
log = self.get_log('RemoteDiagnostics')
|
||||
|
||||
if command == "disconnect":
|
||||
subprocess.Popen(['killall', 'ngrok'])
|
||||
self.write_json({'message': "Succesfully disconnected"})
|
||||
|
||||
if command == "connect":
|
||||
try:
|
||||
url = 'https://tinyurl.com/1f-remote?code={}'.format(code)
|
||||
with urlopen(url) as response:
|
||||
body = response.read()
|
||||
|
||||
os.makedirs("/tmp/ngrok", exist_ok=True)
|
||||
with open("/tmp/ngrok/1f-ngrok.sh", 'wb') as f:
|
||||
f.write(body)
|
||||
|
||||
subprocess.Popen(['/bin/bash', "/tmp/ngrok/1f-ngrok.sh"])
|
||||
self.write_json({'success': True})
|
||||
except Exception as e:
|
||||
log.info("Failed: {}".format(str(e)))
|
||||
self.write_json({
|
||||
'success': False,
|
||||
'code': e.code or None,
|
||||
'message': e.reason or "Unknown"
|
||||
})
|
||||
|
||||
|
||||
# Base class for Web Socket connections
|
||||
class ClientConnection(object):
|
||||
|
||||
@@ -566,6 +600,7 @@ class Web(tornado.web.Application):
|
||||
(r'/api/video', bbctrl.VideoHandler),
|
||||
(r'/api/screen-rotation', ScreenRotationHandler),
|
||||
(r'/api/time', TimeHandler),
|
||||
(r'/api/remote-diagnostics', RemoteDiagnosticsHandler),
|
||||
(r'/(.*)', StaticFileHandler, {
|
||||
'path': bbctrl.get_resource('http/'),
|
||||
'default_filename': 'index.html'
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<script lang="ts">
|
||||
import RemoteDiagnosticsDialog from "$dialogs/RemoteDiagnosticsDialog.svelte";
|
||||
import Button, { Label } from "@smui/button";
|
||||
|
||||
let showRemoteDiagnosticsDialog = false;
|
||||
</script>
|
||||
|
||||
<RemoteDiagnosticsDialog bind:open={showRemoteDiagnosticsDialog} />
|
||||
|
||||
<h2>Support & Contact Info</h2>
|
||||
<p>
|
||||
Please visit
|
||||
@@ -10,6 +16,14 @@
|
||||
for a variety of support resources, and to find our contact information.
|
||||
</p>
|
||||
|
||||
<Button
|
||||
touch
|
||||
variant="raised"
|
||||
on:click={() => (showRemoteDiagnosticsDialog = true)}
|
||||
>
|
||||
<Label>Remote Diagnostics</Label>
|
||||
</Button>
|
||||
|
||||
<h2>Discussion Forum</h2>
|
||||
<p>
|
||||
Check out our support and discussion forum at
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<script lang="ts">
|
||||
import * as api from "$lib/api";
|
||||
import TextField from "@smui/textfield";
|
||||
import Dialog, {
|
||||
Title,
|
||||
Content,
|
||||
Actions,
|
||||
InitialFocus,
|
||||
} from "@smui/dialog";
|
||||
import Button, { Label } from "@smui/button";
|
||||
import { virtualKeyboardChange } from "$lib/CustomActions";
|
||||
|
||||
export let open;
|
||||
|
||||
let code = "";
|
||||
|
||||
async function onContinue() {
|
||||
const url = `remote-diagnostics?command=connect&code=${code}`;
|
||||
const result = await api.GET(url);
|
||||
|
||||
if (result.code === 401) {
|
||||
alert("The 6-digit code you provided was incorrect");
|
||||
} else {
|
||||
alert("Success!");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<Dialog
|
||||
bind:open
|
||||
scrimClickAction=""
|
||||
aria-labelledby="remote-diagnostics-dialog-title"
|
||||
aria-describedby="remote-diagnostics-dialog-content"
|
||||
>
|
||||
<Title id="remote-diagnostics-dialog-title">Remote Diagnostics</Title>
|
||||
|
||||
<Content id="remote-diagnostics-dialog-content">
|
||||
<p>
|
||||
This feature enables remote diagnosis of customer issues. It
|
||||
requires a 6-digit code that is provided by Onefinity support during
|
||||
a live support session.
|
||||
</p>
|
||||
|
||||
<TextField
|
||||
bind:value={code}
|
||||
label="6-digit code"
|
||||
type="number"
|
||||
variant="filled"
|
||||
invalid={code?.length !== 6}
|
||||
use={[InitialFocus, virtualKeyboardChange((v) => (code = v))]}
|
||||
/>
|
||||
</Content>
|
||||
|
||||
<Actions>
|
||||
<Button>
|
||||
<Label>Cancel</Label>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
defaultAction
|
||||
on:click={onContinue}
|
||||
disabled={code?.length !== 6}
|
||||
>
|
||||
<Label>Continue</Label>
|
||||
</Button>
|
||||
</Actions>
|
||||
</Dialog>
|
||||
Reference in New Issue
Block a user