Skip to content

Commit

Permalink
Added auto-updater
Browse files Browse the repository at this point in the history
  • Loading branch information
lorypelli committed Mar 20, 2024
1 parent 3256403 commit c5f6e9e
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 10 deletions.
92 changes: 92 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import (
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
Expand All @@ -16,6 +19,8 @@ import (
"github.com/wailsapp/wails/v2/pkg/runtime"
)

const APP_VERSION = "1.1.0"

// App struct
type App struct {
ctx context.Context
Expand All @@ -29,6 +34,13 @@ func NewApp() *App {
// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
bin, _ := os.Executable()
path := filepath.Dir(bin)
bat := filepath.Join(path, "temp.bat")
_, err := os.Stat(bat)
if (!os.IsNotExist(err)) {
os.Remove(bat)
}
a.ctx = ctx
}

Expand Down Expand Up @@ -59,6 +71,23 @@ type WSResponse struct {
Message string
}

type Update struct {
IsLatest bool
Version string
Description string
Error string
}

type Github struct {
Tag_name string
Body string
Assets []Download
}

type Download struct {
Browser_download_url string
}

func (a *App) HTTP(method string, url string, headers []Header, query []Query, body string) HTTPResponse {
data := []byte(body)
for i := 0; i < len(query); i++ {
Expand Down Expand Up @@ -164,3 +193,66 @@ func Connect(res *http.Response, ws *websocket.Conn, connected bool, a *App) {
time.Sleep(1 * time.Second)
}
}

func (a *App) CheckUpdates() Update {
res, err := http.Get("https://api.github.com/repos/lorypelli/FetchTTP/releases/latest")
if err != nil {
return Update{
true, "", "", err.Error(),
}
}
jsonBody := Github{}
bytes, _ := io.ReadAll(res.Body)
j.Unmarshal(bytes, &jsonBody)
tag := jsonBody.Tag_name
description := jsonBody.Body
version := strings.ReplaceAll(tag, ".", "")
currentVersion := strings.ReplaceAll(APP_VERSION, ".", "")
version_int, _ := strconv.Atoi(version)
currentVersion_int, _ := strconv.Atoi(currentVersion)
if version_int > currentVersion_int {
return Update{
false, tag, description, "",
}
}
return Update{
true, "", "", "",
}
}

func (a *App) Update() {
res, err := http.Get("https://api.github.com/repos/lorypelli/FetchTTP/releases/latest")
if err != nil {
return
}
jsonBody := Github{}
bytes, _ := io.ReadAll(res.Body)
j.Unmarshal(bytes, &jsonBody)
bin, _ := os.Executable()
path, _ := filepath.Abs(bin)
res, err = http.Get(jsonBody.Assets[0].Browser_download_url)
if err != nil {
return
}
bytes, _ = io.ReadAll(res.Body)
newPath := strings.Split(path, ".exe")[0] + "1.exe"
file, _ := os.Create(newPath)
file.Write(bytes)
tempPath := strings.Split(path, "FetchTTP.exe")[0] + "temp.bat"
tempFile, _ := os.Create(tempPath)
pathWithoutExe := filepath.Dir(path)
exe := filepath.Base(path)
p_new := filepath.Base(newPath)
commands := `@echo off
cd ` + pathWithoutExe + `
taskkill /IM ` + exe + `
taskkill /IM ` + exe + `
del ` + exe + `
rename "` + p_new + `" "` + exe + `"
exit`
tempFile.WriteString(commands)
cmd := exec.Command("cmd.exe", "/C", tempPath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
}
139 changes: 132 additions & 7 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
<script setup lang="ts">
import { ElNotification, ElTabPane, ElTabs } from 'element-plus';
import HTTP from './components/HTTP.vue';
import WS from './components/WS.vue';
import { ElMessageBox, ElNotification, ElTabPane, ElTabs } from 'element-plus';
import HTTP, { handleTab as HTTPTab } from './components/HTTP.vue';
import WS, { handleTab as WSTab } from './components/WS.vue';
import Updater from './components/Updater.vue';
import 'element-plus/dist/index.css';
import 'primevue/resources/themes/aura-light-green/theme.css';
import { ref } from 'vue';
import { handleTab as HTTPTab } from './components/HTTP.vue';
import { handleTab as WSTab } from './components/WS.vue';
import { h, ref } from 'vue';
import { CheckUpdates, Update as U } from '../wailsjs/go/main/App.js';
defineOptions({
name: 'App',
components: {
ElTabPane,
ElTabs,
HTTP,
WS
WS,
Updater
}
});
</script>

<script lang="ts">
interface Update {
IsLatest: boolean,
Version: string,
Description: string,
Error: string
}
const selectedTab = ref('HTTP');
export default {
methods: {
Expand Down Expand Up @@ -48,6 +55,69 @@ export default {
}
]
},
{
label: 'Check for Updates',
onClick: () => {
try {
CheckUpdates().then((res: Update) => {
if (res.Error) {
ElNotification({
title: 'Error while checking for updates!',
message: res.Error,
type: 'error',
position: 'bottom-right'
});
return;
}
if (res.IsLatest) {
ElMessageBox({
message: 'You are using latest version'
}).catch(() => { });
}
else {
ElMessageBox({
title: 'A new version is avaible!\nDo you want to update?',
message: h(Updater, {
version: res.Version,
description: res.Description
}),
confirmButtonText: 'Yes',
showCancelButton: true,
cancelButtonText: 'No',
showClose: false,
closeOnClickModal: false,
closeOnHashChange: false,
closeOnPressEscape: false,
center: true
})
.then(() => {
ElMessageBox({
title: 'Warning!',
message: 'The app will now exit and you will need to re-open it manually',
type: 'warning',
showClose: false,
closeOnClickModal: false,
closeOnHashChange: false,
closeOnPressEscape: false,
center: true
})
.then(() => {
U();
});
})
.catch(() => { });
}
});
}
catch {
ElNotification({
title: 'Error while checking for updates!',
type: 'error',
position: 'bottom-right'
});
}
}
},
{
label: 'Open Devtools',
onClick: () => {
Expand All @@ -62,6 +132,61 @@ export default {
]
});
}
},
mounted() {
try {
CheckUpdates().then((res: Update) => {
if (res.Error) {
ElNotification({
title: 'Error while checking for updates!',
message: res.Error,
type: 'error',
position: 'bottom-right'
});
return;
}
if (!res.IsLatest) {
ElMessageBox({
title: 'A new version is avaible!\nDo you want to update?',
message: h(Updater, {
version: res.Version,
description: res.Description
}),
confirmButtonText: 'Yes',
showCancelButton: true,
cancelButtonText: 'No',
showClose: false,
closeOnClickModal: false,
closeOnHashChange: false,
closeOnPressEscape: false,
center: true
})
.then(() => {
ElMessageBox({
title: 'Warning!',
message: 'The app will now exit and you will need to re-open it manually',
type: 'warning',
showClose: false,
closeOnClickModal: false,
closeOnHashChange: false,
closeOnPressEscape: false,
center: true
})
.then(() => {
U();
});
})
.catch(() => { });
}
});
}
catch {
ElNotification({
title: 'Error while checking for updates!',
type: 'error',
position: 'bottom-right'
});
}
}
};
</script>
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/Split.vue
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export default {
});
ElMessageBox({
title: 'New Cookie',
message: () => h(ElForm, {
message: h(ElForm, {
labelPosition: 'top'
}, [
h(ElFormItem, {
Expand Down Expand Up @@ -423,7 +423,8 @@ export default {
<ElEmpty
:class="`${['', 'null'].includes(props.response.trim()) ? 'flex' : 'hidden'} justify-center h-scrollbar-partial`"
description="Nothing to display here..." />
<ElText v-if="isText(props.header) && !['', 'null'].includes(props.response.trim())">{{ props.response }}</ElText>
<ElText v-if="isText(props.header) && !['', 'null'].includes(props.response.trim())">{{
props.response }}</ElText>
<div
:class="`${isText(props.header) ? 'hidden' : 'flex'} justify-center items-center h-scrollbar-full`">
<img v-if="isImage(props.header)" :src="props.url" />
Expand Down
25 changes: 25 additions & 0 deletions frontend/src/components/Updater.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script setup lang="ts">
import { ElInput, ElText } from 'element-plus';
import { ref } from 'vue';
defineOptions({
// eslint-disable-next-line vue/multi-word-component-names
name: 'Updater',
components: {
ElText,
ElInput
}
});
const props = defineProps<{
version: string,
description: string
}>();
const updateVersion = ref(props.version);
const updateDescription = ref(props.description);
</script>

<template>
<div class="space-y-1">
<ElInput class="flex flex-col items-center" readonly v-model="updateVersion" />
<ElInput class="flex flex-col" type="textarea" resize="none" readonly v-model="updateDescription" />
</div>
</template>
1 change: 0 additions & 1 deletion frontend/src/components/WS.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ const tabs = ref([
}
]);
export function handleTab(targetName: TabPaneName | undefined, action: 'add' | 'remove') {
console.log(targetName);
switch (action) {
case 'add': {
const newTabIndex = `${++tabIndex}`;
Expand Down
4 changes: 4 additions & 0 deletions frontend/wailsjs/go/main/App.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
// This file is automatically generated. DO NOT EDIT
import {main} from '../models';

export function CheckUpdates():Promise<main.Update>;

export function HTTP(arg1:string,arg2:string,arg3:Array<main.Header>,arg4:Array<main.Query>,arg5:string):Promise<main.HTTPResponse>;

export function Update():Promise<void>;

export function WS(arg1:string,arg2:Array<main.Header>,arg3:Array<main.Query>,arg4:boolean):Promise<void>;
8 changes: 8 additions & 0 deletions frontend/wailsjs/go/main/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT

export function CheckUpdates() {
return window['go']['main']['App']['CheckUpdates']();
}

export function HTTP(arg1, arg2, arg3, arg4, arg5) {
return window['go']['main']['App']['HTTP'](arg1, arg2, arg3, arg4, arg5);
}

export function Update() {
return window['go']['main']['App']['Update']();
}

export function WS(arg1, arg2, arg3, arg4) {
return window['go']['main']['App']['WS'](arg1, arg2, arg3, arg4);
}

0 comments on commit c5f6e9e

Please sign in to comment.