Skip to content

Commit

Permalink
Working on magic upload
Browse files Browse the repository at this point in the history
  • Loading branch information
eliasbakken committed Jun 5, 2024
1 parent cbfed1a commit 366bd02
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 16 deletions.
85 changes: 78 additions & 7 deletions client/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,10 @@
<span class="red">{{ this.computeSizeCheckText() }}</span>
</div>
<div class="xs1 pa1">
<ProgressBar ref="magicprogressbar" v-show="state === 'MAGIC'" />
<ProgressBar
ref="magicprogressbar"
v-show="state === 'MAGIC' || state === 'UPLOADING_MAGIC'"
/>
{{ this.options.magicmode ? "" : "Choose image to install" }}
</div>
<div class="xs1 pa1">
Expand Down Expand Up @@ -282,7 +285,9 @@ export default {
return "";
},
computeMagicButtonText() {
return this.state == "MAGIC" ? "Cancel" : "Magic";
return this.state == "MAGIC" || this.state == "UPLOADING_MAGIC"
? "Cancel"
: "Magic";
},
flashDirection() {
return this.flash.selectedMethod == 1 ? "left" : "right";
Expand Down Expand Up @@ -310,6 +315,8 @@ export default {
if (this.selectedMethod.id == 0 && this.selectedRebuildImage) return true;
if (this.selectedMethod.id == 1 && this.selectedRefactorImage)
return true;
if (this.selectedMethod.id == 2 && this.selectedUploadImage.file)
return true;
return false;
},
isTransferButtonVisible() {
Expand Down Expand Up @@ -363,6 +370,65 @@ export default {
}
});
},
async startMagicUpload() {
let self = this;
if (this.state == "IDLE") {
this.state = "UPLOADING_MAGIC";
await axios
.put(`/api/upload_magic_start`, {
filename: self.file.name,
size: self.file.size,
start_time: Date.now(),
})
.then(function (response) {
self.status = response.data["success"];
self.magicUploadLocalFile();
self.checkProgress();
});
} else {
this.apiCall("upload_cancel");
}
},
async magicUploadLocalFile() {
console.log("magig upload local file");
const CHUNK_SIZE = 3 * 1024 * 1024;
let self = this;
var reader = new FileReader();
var offset = 0;
var filesize = this.file.size;
console.log(filesize);
reader.onload = function () {
console.log("onload");
var result = reader.result;
var chunk = result;
axios
.post(`/api/upload_magic_chunk`, {
chunk: chunk,
})
.then(function (response) {
const status = response.data;
if (status.success && self.state == "UPLOADING_MAGIC") {
offset += CHUNK_SIZE;
if (offset <= filesize) {
var slice = self.file.slice(offset, offset + CHUNK_SIZE);
reader.readAsDataURL(slice);
} else {
offset = filesize;
self.apiCall("upload_finish");
}
} else {
self.apiCall("upload_cancel");
}
});
};
if (this.file) {
var slice = this.file.slice(offset, offset + CHUNK_SIZE);
reader.readAsDataURL(slice);
self.fileName = this.file.name;
}
},
async uploadSelected() {
let self = this;
if (this.state == "IDLE") {
Expand All @@ -379,7 +445,7 @@ export default {
self.checkProgress();
});
} else {
this.apiCall('upload_cancel')
this.apiCall("upload_cancel");
}
},
async uploadLocalFile() {
Expand All @@ -405,10 +471,10 @@ export default {
reader.readAsDataURL(slice);
} else {
offset = filesize;
self.apiCall('upload_finish');
self.apiCall("upload_finish");
}
} else {
self.apiCall('upload_cancel')
self.apiCall("upload_cancel");
}
});
};
Expand All @@ -422,15 +488,19 @@ export default {
onMagicButtonClick() {
if (this.selectedMethod.id == 0) {
this.selectedGithubImage = this.selectedRebuildImage;
this.startMagic();
} else if (this.selectedMethod.id == 1) {
this.selectedGithubImage = this.selectedRefactorImage;
this.startMagic();
} else if (this.selectedMethod.id == 2) {
this.selectedGithubImage = this.selectedLocalImage;
this.startMagicUpload();
}
this.startMagic();
},
async startMagic() {
let self = this;
if (this.state == "IDLE") {
this.state = "MAGIC"
this.state = "MAGIC";
await axios
.put(`/api/start_magic`, {
filename: this.selectedGithubImage["name"],
Expand Down Expand Up @@ -478,6 +548,7 @@ export default {
"INSTALLING",
"BACKUPING",
"MAGIC",
"UPLOADING_MAGIC",
].includes(this.state)
) {
this.setProgress({ progress: data.progress });
Expand Down
1 change: 1 addition & 0 deletions reflash/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
require (
github.com/grafana/tail v0.0.0-20230510142333-77b18831edf0 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
Expand Down
2 changes: 2 additions & 0 deletions reflash/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
Expand Down
88 changes: 79 additions & 9 deletions reflash/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/grafana/tail"
"github.com/pelletier/go-toml/v2"
"github.com/ulikunitz/xz"
"golang.org/x/exp/slices"
)

Expand Down Expand Up @@ -88,15 +89,16 @@ type Settings struct {
}

const (
IDLE = "IDLE"
DOWNLOADING = "DOWNLOADING"
UPLOADING = "UPLOADING"
INSTALLING = "INSTALLING"
BACKUPING = "BACKUPING"
MAGIC = "MAGIC"
FINISHED = "FINISHED"
CANCELLED = "CANCELLED"
ERROR = "ERROR"
IDLE = "IDLE"
DOWNLOADING = "DOWNLOADING"
UPLOADING = "UPLOADING"
INSTALLING = "INSTALLING"
BACKUPING = "BACKUPING"
MAGIC = "MAGIC"
UPLOADING_MAGIC = "UPLOADING_MAGIC"
FINISHED = "FINISHED"
CANCELLED = "CANCELLED"
ERROR = "ERROR"
)

const (
Expand Down Expand Up @@ -190,6 +192,8 @@ func ServerInit() {
http.HandleFunc("/api/cancel_backup", cancelBackup)
http.HandleFunc("/api/start_magic", startMagic)
http.HandleFunc("/api/cancel_magic", cancelMagic)
http.HandleFunc("/api/upload_magic_start", uploadMagicStart)
http.HandleFunc("/api/upload_magic_chunk", uploadMagicChunk)
http.HandleFunc("/api/get_progress", getProgress)
http.HandleFunc("/api/check_file_integrity", checkFileIntegrity)
http.HandleFunc("/api/run_install_finished_commands", runInstallFinishedCommands)
Expand Down Expand Up @@ -342,6 +346,72 @@ func uploadStart(w http.ResponseWriter, r *http.Request) {
sendResponse(w, nil)
}

func uploadMagicStart(w http.ResponseWriter, r *http.Request) {
var data *Download = &Download{}
reqBody, _ := io.ReadAll(r.Body)
json.Unmarshal(reqBody, &data)

state.Filename = data.Filename
state.StartTime = data.StartTime
state.BytesNow = 0
state.BytesTotal = data.Size
state.State = UPLOADING_MAGIC

timeStart = time.Now()
logInfo("Starting magic upload at " + timeStart.Format("15:04:05"))
logInfo("Filename: " + state.Filename)

path := "/tmp/decompressed.img"
os.Create(path)
sendResponse(w, nil)
}

func uploadMagicChunk(w http.ResponseWriter, r *http.Request) {
var chunk *Chunk = &Chunk{}
reqBody, _ := io.ReadAll(r.Body)
json.Unmarshal(reqBody, &chunk)

decoded, err := base64.StdEncoding.DecodeString(chunk.Encoded[37:])

path := "/tmp/decompressed.img"

if state.State == CANCELLED {
response := map[string]bool{"success": false}
json.NewEncoder(w).Encode(response)
return
}

reader, err := xz.NewReader(bytes.NewReader(decoded))
if err != nil {
log.Fatal(err)
}

var decompressedData bytes.Buffer
if _, err := io.Copy(&decompressedData, reader); err != nil {
log.Fatal("Failed to copy")
log.Fatal(err)
}

outFile, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
log.Fatal("Failed to open file")
log.Fatal(err)
}

if _, err := outFile.Write(decompressedData.Bytes()); err != nil {
log.Fatal("Failed write")
log.Fatal(err)
}
if err := outFile.Close(); err != nil {
log.Fatal(err)
}
state.BytesNow += len(decoded)
state.Progress = float64(state.BytesNow) * 100 / float64(state.BytesTotal)

response := map[string]bool{"success": true}
json.NewEncoder(w).Encode(response)
}

func uploadChunk(w http.ResponseWriter, r *http.Request) {
var chunk *Chunk = &Chunk{}
reqBody, _ := io.ReadAll(r.Body)
Expand Down

0 comments on commit 366bd02

Please sign in to comment.