#450 Airtable link to submit bugs (#475)

Co-authored-by: neil molina <neil@neils-MacBook-Pro.local>
This commit is contained in:
Neil 2023-04-19 10:40:41 +08:00 committed by GitHub
parent 434af3e7e0
commit 2d41120e28
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 47 deletions

View file

@ -1,21 +1,17 @@
import { ipcMain, app, BrowserWindow } from "electron";
import { createReadStream, statSync } from "fs";
import { getInstalledPackages } from "./tea-dir";
import { readSessionData, writeSessionData } from "./auth";
import type { Packages, Session } from "../../src/libs/types";
import * as log from "electron-log";
import { post } from "./v1-client";
import { deepReadDir, deletePackageFolder } from "./tea-dir";
import path from "path";
import { syncLogsAt } from "./v1-client";
import { installPackage, openTerminal, syncPantry } from "./cli";
import initializeTeaCli from "./initialize";
import { getUpdater } from "./auto-updater";
import fetch from "node-fetch";
import { loadPackageCache, writePackageCache } from "./package";
import { nanoid } from "nanoid";
let teaProtocolPath = ""; // this should be empty string
export const setProtocolPath = (path: string) => {
@ -106,38 +102,19 @@ export default function initializeHandlers() {
ipcMain.handle("submit-logs", async () => {
try {
log.info("syncing logs");
const logDir = path.join(app.getPath("home"), "Library/Logs/tea");
// ['/Users/neil/Library/Logs/tea/main.log']
const logFiles = await deepReadDir({ dir: logDir });
let deviceId = "";
const files = logFiles.map((p) => {
const paths = p.split("/");
deviceId = paths[2]; // temp hack use developers username instead of gui_id
return paths.pop();
});
const { device_id } = await readSessionData();
const logId = [device_id, nanoid()].join("---");
const signedUrls = await post<{ [key: string]: string }>(`/gui/${deviceId}/sync-log-files`, {
files
});
if (signedUrls) {
for (const key in signedUrls) {
const fileIndex = files.indexOf(key);
const filePath = logFiles[fileIndex];
if (filePath) {
const payload = createReadStream(filePath);
const response = await fetch(signedUrls[key], {
method: "PUT",
body: payload,
headers: {
"Content-Length": statSync(filePath).size.toString()
}
});
log.info("uploading log:", key, response.status);
}
}
}
// sync in background
syncLogsAt(logId)
.then(() => {
log.info("logs synced:", logId);
})
.catch((error) => {
log.error(error);
});
return `log files(${logFiles.length}) has been uploaded to S3 logs/${deviceId}`;
return logId;
} catch (error) {
log.error(error);
return error.message;

View file

@ -1,7 +1,11 @@
import { app } from "electron";
import axios from "axios";
import path from "path";
import * as log from "electron-log";
import bcrypt from "bcryptjs";
import { createReadStream, statSync } from "fs";
import { deepReadDir } from "./tea-dir";
import fetch from "node-fetch";
import { readSessionData, type Session } from "./auth";
@ -77,4 +81,35 @@ async function getHeaders(path: string, session: Session) {
};
}
export async function syncLogsAt(prefix: string) {
const logDir = path.join(app.getPath("home"), "Library/Logs/tea");
// ['/Users/neil/Library/Logs/tea/main.log']
const logFiles = await deepReadDir({ dir: logDir });
const files = logFiles.map((p) => {
const paths = p.split("/");
return paths.pop();
});
const signedUrls = await post<{ [key: string]: string }>(`/gui/${prefix}/sync-log-files`, {
files
});
if (signedUrls) {
for (const key in signedUrls) {
const fileIndex = files.indexOf(key);
const filePath = logFiles[fileIndex];
if (filePath) {
const payload = createReadStream(filePath);
const response = await fetch(signedUrls[key], {
method: "PUT",
body: payload,
headers: {
"Content-Length": statSync(filePath).size.toString()
}
});
log.info("uploading log:", key, response.status);
}
}
}
}
export default get;

View file

@ -1,26 +1,34 @@
<script lang="ts">
import { shellOpenExternal } from "@native";
import { navStore } from "$libs/stores";
import { shellOpenExternal, submitLogs } from "@native";
// import { navStore } from "$libs/stores";
import LoginButton from "./login-button.svelte";
const { sideNavOpen } = navStore;
// const { sideNavOpen } = navStore;
const toggleSideNav = () => {
sideNavOpen.update((v) => !v);
};
// const toggleSideNav = () => {
// sideNavOpen.update((v) => !v);
// };
const submitBugReport = async () => {
const logId = await submitLogs();
const bugFormUrl = `https://airtable.com/shravDxWeNwwpPkFV?prefill_log_id=${logId}`;
shellOpenExternal(bugFormUrl);
}
</script>
<div class="mr-1 flex h-full items-center justify-end gap-2 p-2">
<button
class="border-gray group flex h-[28px] w-[28px] items-center justify-center rounded-sm border hover:bg-[#e1e1e1]"
on:click={() => shellOpenExternal("https://github.com/teaxyz/gui/issues/new")}
on:click={() => submitBugReport()}
>
<div class="icon-bug text-l text-gray flex group-hover:text-black" />
</button>
<!--
unused: the popout menu only have sync logs atm
<button
class="border-gray group flex h-[28px] w-[28px] items-center justify-center rounded-sm border hover:bg-[#e1e1e1]"
on:click={toggleSideNav}
>
<div class="icon-gear text-l text-gray flex group-hover:text-black" />
</button>
</button> -->
<LoginButton />
</div>

View file

@ -202,7 +202,7 @@ export const getProtocolPath = async (): Promise<string> => {
return path;
};
export const submitLogs = async () => {
export const submitLogs = async (): Promise<string> => {
const response = await ipcRenderer.invoke("submit-logs");
return response;
};

View file

@ -352,8 +352,8 @@ export const relaunch = () => {
export const getProtocolPath = async (): Promise<string> => "";
export const submitLogs = async () => {
return "synced!";
export const submitLogs = async (): Promise<string> => {
return "deviceId---logid";
};
export const isPackageInstalled = async (_v?: string): Promise<boolean> => {