fix: #44, #45
continuous-integration/drone/tag Build is passing Details

feat/muzan v0.1.5
Evan Chen 2021-11-03 16:21:49 +08:00
parent 38afcf64cf
commit 3a64217a10
7 changed files with 104 additions and 11 deletions

View File

@ -2,10 +2,12 @@ package configui
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strconv"
)
func (cui *ConfigUI) ListFiles(w http.ResponseWriter, r *http.Request) {
@ -27,11 +29,63 @@ func (cui *ConfigUI) GetFile(w http.ResponseWriter, r *http.Request) {
if err != nil {
panic(err)
}
stat, err := os.Stat(file.Path)
if err != nil {
panic(err)
}
response, err := json.Marshal(map[string]string{
"path": file.Path,
"name": file.Name,
"action": file.Action,
"data": string(data),
"delta": strconv.Itoa(int(stat.Size())),
})
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/json")
w.Write(response)
}
func (cui *ConfigUI) GetDelta(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
delta, err := strconv.ParseInt(r.URL.Query().Get("delta"), 10, 64)
if err != nil {
panic(err)
}
file, err := cui.File(name)
if err != nil {
response(w, 404, []byte("file not found"))
return
}
f, err := os.Open(file.Path)
if err != nil {
panic(err)
}
defer f.Close()
stat, err := os.Stat(file.Path)
if err != nil {
panic(err)
}
if delta > stat.Size() {
panic(fmt.Errorf("delta(%d) is larger than file size(%d)", delta, stat.Size()))
}
if stat.Size() < delta {
panic(fmt.Errorf("delta(%d) is smaller than file size(%d)", delta, stat.Size()))
}
buf := make([]byte, stat.Size()-delta)
_, err = f.ReadAt(buf, delta)
if err != nil {
panic(err)
}
response, err := json.Marshal(map[string]string{
"path": file.Path,
"name": file.Name,
"action": file.Action,
"data": string(buf),
"delta": strconv.Itoa(int(stat.Size())),
})
if err != nil {
panic(err)

View File

@ -33,6 +33,7 @@ func response(w http.ResponseWriter, status int, body []byte) (int, error) {
}
func abort(w http.ResponseWriter, err interface{}) (int, error) {
log.Println(err)
switch v := err.(type) {
case int:
w.WriteHeader(v)

File diff suppressed because one or more lines are too long

View File

@ -59,6 +59,13 @@ func (cui *ConfigUI) mux() *http.ServeMux {
w.WriteHeader(404)
}
})
cuiR.HandleFunc("/api/delta", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
cui.GetDelta(w, r)
} else {
w.WriteHeader(404)
}
})
cuiR.HandleFunc("/api/apply", func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
cui.Apply(w, r)

View File

@ -2,12 +2,13 @@
<footer class="footer">
<div class="content has-text-right">
<p>
<strong>Configui</strong> {{.Version}} by <a href="https://kumoly.io/evanchen">Evan Chen</a>.
<strong>Configui</strong> {{.Version}} by <a href="mailto:evanchen@kumoly.io">Evan Chen</a>.
</p>
</div>
</footer>
<script src="{{.BaseUrl}}public/ace/js/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="{{.BaseUrl}}public/ace/js/ext-beautify.js" type="text/javascript" charset="utf-8"></script>
<script src="{{.BaseUrl}}public/ace/js/ext-searchbox.js" type="text/javascript" charset="utf-8"></script>
{{template "base/script" .}}
<!-- <script src="/public/js/main.js"></script> -->
</body>

View File

@ -1,30 +1,30 @@
{{define "base/script"}}
<script>
window.ToolIsFollow = false;
window.LastDelta = 0;
window.ContentChanged = false;
async function FileGet(follower=false){
let f = ''
if (Active == 'ConfigUI') {
if (follower) f = '?f=true'
const res = await fetch('{{.BaseUrl}}api/conf'+f)
async function FileGet(){
if (Active == '{{.AppName}}') {
const res = await fetch('{{.BaseUrl}}api/conf')
.catch(err=>{console.log(err);return;});
const body = await res.text();
if(!res.ok){
Catch(res)
return
}
LastDelta = 0;
editor.session.setValue(body);
}
else {
if (follower) f = '&f=true'
const res = await fetch('{{.BaseUrl}}api/file?name=' + Active + f)
const res = await fetch('{{.BaseUrl}}api/file?name=' + Active)
.catch(err=>{console.log(err);return;});
const body = await res.json();
if(!res.ok){
Catch(res)
return
}
LastDelta = body.delta;
editor.session.setValue(body.data);
}
}
@ -75,6 +75,24 @@ async function FileApply(){
}
}
async function FileDelta(){
if (Active == '{{.AppName}}') {
await FileGet()
return
}
else {
const res = await fetch('{{.BaseUrl}}api/delta?f=true&name=' + Active+'&delta='+LastDelta)
.catch(err=>{console.log(err);return;});
const body = await res.json();
if(!res.ok){
Catch(res)
return
}
LastDelta = body.delta;
editor.session.setValue(editor.getValue()+body.data);
}
}
async function Catch(res){
{{/* console.trace()
console.log(res) */}}
@ -107,7 +125,7 @@ function setResult(){
// for follow mode
setInterval((async ()=>{
if (ToolIsFollow){
await FileGet(true)
await FileDelta()
editor.gotoLine(editor.session.getLength());
}
}), 1000)

View File

@ -164,20 +164,24 @@ function toolSetFontSize(obj){
function toolFollow(){
if (ToolIsFollow){
ToolIsFollow = false
ToolIsFollow = false;
editor.setReadOnly({{.File.RO}});
let el = document.getElementById('toolFollow');
let icon = document.getElementById('toolFollowIcon');
el.classList.remove('is-primary');
icon.classList.remove('icn-spinner');
icon.innerText='sync_disabled';
} else {
ToolIsFollow = true
editor.setReadOnly(true);
let el = document.getElementById('toolFollow');
let icon = document.getElementById('toolFollowIcon');
el.classList.add('is-primary');
icon.innerText='sync';
icon.classList.add('icn-spinner');
editor.gotoLine(editor.session.getLength());
FileGet().then(()=>{
ToolIsFollow = true
})
}
}