From 63bdf7c564d6262e3e9813f96e023f725d4daaae Mon Sep 17 00:00:00 2001
From: nopdan <xci@live.com>
Date: Sat, 9 Mar 2024 18:09:26 +0800
Subject: [PATCH] fix: upload file

---
 build.ps1                        |   1 +
 frontend/components.d.ts         |   5 -
 frontend/src/components/Text.vue |   2 +-
 internal/serve/assets/tmpl.html  | 310 -------------------------------
 internal/serve/tmpl.go           | 131 -------------
 pkg/server/dist/placeholder      |   0
 pkg/server/race.go               |   4 +-
 pkg/server/serve.go              | 201 --------------------
 8 files changed, 4 insertions(+), 650 deletions(-)
 delete mode 100644 internal/serve/assets/tmpl.html
 delete mode 100644 internal/serve/tmpl.go
 delete mode 100644 pkg/server/dist/placeholder
 delete mode 100644 pkg/server/serve.go

diff --git a/build.ps1 b/build.ps1
index 1e34a07..c7e1046 100644
--- a/build.ps1
+++ b/build.ps1
@@ -3,6 +3,7 @@ cd frontend
 bun install
 bun run build
 cd ..
+rm pkg/server/dist -r
 xcopy frontend\dist\ pkg\server\dist\ /E /Y
 
 go mod tidy
diff --git a/frontend/components.d.ts b/frontend/components.d.ts
index b082a1d..d3b31b6 100644
--- a/frontend/components.d.ts
+++ b/frontend/components.d.ts
@@ -16,9 +16,7 @@ declare module "@vue/runtime-core" {
     CollisionDistBar: (typeof import("./src/components/Result/CollisionDistBar.vue"))["default"];
     CombsDescription: (typeof import("./src/components/Result/CombsDescription.vue"))["default"];
     CombsDistBar: (typeof import("./src/components/Result/CombsDistBar.vue"))["default"];
-    Compare: (typeof import("./src/components/Compare.vue"))["default"];
     ComparedBars: (typeof import("./src/components/Result/comparedBars.vue"))["default"];
-    Data: (typeof import("./src/components/Data.vue"))["default"];
     FingerPie: (typeof import("./src/components/Result/FingerPie.vue"))["default"];
     FingersDescription: (typeof import("./src/components/Result/FingersDescription.vue"))["default"];
     HandComp: (typeof import("./src/components/Result/HandComp.vue"))["default"];
@@ -28,8 +26,6 @@ declare module "@vue/runtime-core" {
     MultiResult: (typeof import("./src/components/MultiResult.vue"))["default"];
     NButton: (typeof import("naive-ui"))["NButton"];
     NCard: (typeof import("naive-ui"))["NCard"];
-    NDescriptions: (typeof import("naive-ui"))["NDescriptions"];
-    NDescriptionsItem: (typeof import("naive-ui"))["NDescriptionsItem"];
     NDivider: (typeof import("naive-ui"))["NDivider"];
     NDrawer: (typeof import("naive-ui"))["NDrawer"];
     NDrawerContent: (typeof import("naive-ui"))["NDrawerContent"];
@@ -41,7 +37,6 @@ declare module "@vue/runtime-core" {
     NRadio: (typeof import("naive-ui"))["NRadio"];
     NRadioGroup: (typeof import("naive-ui"))["NRadioGroup"];
     NSelect: (typeof import("naive-ui"))["NSelect"];
-    NSpace: (typeof import("naive-ui"))["NSpace"];
     NSwitch: (typeof import("naive-ui"))["NSwitch"];
     NTag: (typeof import("naive-ui"))["NTag"];
     NText: (typeof import("naive-ui"))["NText"];
diff --git a/frontend/src/components/Text.vue b/frontend/src/components/Text.vue
index 177699d..06e8a58 100644
--- a/frontend/src/components/Text.vue
+++ b/frontend/src/components/Text.vue
@@ -48,7 +48,7 @@ const _Type = computed(() => {
 function tidyPath(path: string) {
   const index = path.lastIndexOf(props._type);
   let name = path;
-  if (index > 0) {
+  if (index != -1) {
     name = path.substring(index + 5);
   }
   name = name.replace(".txt", "");
diff --git a/internal/serve/assets/tmpl.html b/internal/serve/assets/tmpl.html
deleted file mode 100644
index 3a809d1..0000000
--- a/internal/serve/assets/tmpl.html
+++ /dev/null
@@ -1,310 +0,0 @@
-<!DOCTYPE html>
-<html lang="">
-  <head>
-    <meta charset="UTF-8" />
-    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>{{.TextName}} 赛码结果</title>
-  </head>
-  <style>
-    body {
-      background: rgb(240, 244, 245);
-    }
-
-    #header {
-      display: flex;
-      flex-direction: column;
-      text-align: center;
-      padding-top: 1rem;
-    }
-
-    #textFileName {
-      font-size: x-large;
-      font-weight: bold;
-      padding-bottom: 0.5rem;
-    }
-
-    #content {
-      display: flex;
-      justify-content: center;
-      min-width: fit-content;
-      text-align: left;
-      margin: 0.5rem;
-    }
-
-    .reportCard {
-      display: flex;
-      flex-direction: column;
-      transition: 0.2s;
-      width: 31rem;
-      margin: 0.8rem;
-      padding: 0.8rem;
-      background-color: #fefefe;
-      border: none;
-      border-radius: 10px;
-    }
-
-    .reportCard:hover {
-      box-shadow: 0 0 6px 0 #bbb;
-    }
-
-    .cardBlock.schemaInfo {
-      display: flex;
-      align-items: end;
-      justify-content: start;
-      font-size: larger;
-      font-weight: bold;
-      padding-left: 0.2rem;
-    }
-
-    .isSingle {
-      color: red;
-      padding: 0 1rem;
-    }
-
-    .dictLen {
-      padding-left: 1rem;
-      font-size: 0.8em;
-      color: lightslategray;
-      white-space: nowrap;
-    }
-
-    .dictLenValue {
-      font-size: 0.7em;
-      font-weight: normal;
-    }
-
-    .cardBlock {
-      padding: 0.5rem 0;
-    }
-
-    table {
-      table-layout: fixed;
-    }
-
-    th {
-      color: lightslategray;
-    }
-
-    .tableBasic {
-      width: 80%;
-    }
-
-    .keyRateTitle {
-      text-align: center;
-      font-weight: bold;
-      padding-bottom: 0.5rem;
-    }
-
-    .heatMap {
-      width: 100%;
-      border-spacing: 6px 6px;
-    }
-
-    .key {
-      padding: 0.1rem;
-      border-radius: 5px;
-      box-shadow: 0 0 2px 0 #bbb;
-    }
-
-    td.key {
-      text-align: center;
-    }
-
-    .heatMapRate {
-      text-align: center;
-      font-size: 0.5em;
-      color: rgb(0, 0, 4, 0.4);
-    }
-
-    .fin {
-      font-size: smaller;
-    }
-
-    .finHeatMap td {
-      white-space: nowrap;
-    }
-
-    .tableFeel {
-      width: 100%;
-    }
-
-    .cardBlock.stat {
-      display: flex;
-      align-items: flex-start;
-    }
-
-    .statHead th {
-      padding-right: 0.5rem;
-      white-space: nowrap;
-    }
-
-    .statTable {
-      display: flex;
-      overflow-x: auto;
-    }
-
-    .statTable > table td {
-      padding-right: 0.2rem;
-    }
-
-    #footer {
-      text-align: center;
-    }
-  </style>
-
-  <body>
-    <div id="header">
-      <div id="textFileName">{{.TextName}}</div>
-      <div id="textLen">文本字数 {{.TextLen}}; 非汉字数 {{.NotHanCount}}</div>
-    </div>
-
-    <div id="content">
-      {{range .Results}}
-      <div class="reportCard">
-        <div class="cardBlock schemaInfo">
-          <div class="dictName">{{.DictName}}</div>
-          {{if .Single}}
-          <div class="isSingle"> *单 </div>
-          {{end}}
-          <div class="dictLen">词条数:</div>
-          <div class="dictLenValue">{{.DictLen}}</div>
-        </div>
-
-        <div class="cardBlock">
-          <table class="tableBasic">
-            <tr>
-              <th>码长</th>
-              <th>总键数</th>
-              <th>上屏数</th>
-              <th>缺字数</th>
-            </tr>
-            <tr>
-              <td>{{.CodeLen.PerChar | printf "%.3f"}}</td>
-              <td>{{.CodeLen.Total }}</td>
-              <td>{{.Basic.Commits }}</td>
-              <td>{{.Basic.Lacks }}</td>
-            </tr>
-
-            <tr>
-              <th>打词数</th>
-              <th>打词字数</th>
-              <th>选重数</th>
-              <th>选重字数</th>
-            </tr>
-            <tr>
-              <td>{{.Words.Commits.Count }}</td>
-              <td>{{.Words.Chars.Count }}</td>
-              <td>{{.Collision.Commits.Count }}</td>
-              <td>{{.Collision.Chars.Count }}</td>
-            </tr>
-            <tr>
-              <td>{{.Words.Commits.Rate | toPer }}</td>
-              <td>{{.Words.Chars.Rate | toPer }}</td>
-              <td>{{.Collision.Commits.Rate | toPer }}</td>
-              <td>{{.Collision.Chars.Rate | toPer }}</td>
-            </tr>
-          </table>
-        </div>
-
-        <div class="cardBlock">
-          <table class="tableFeel">
-            <tr>
-              <th>左手</th>
-              <th>左左</th>
-              <th>左右</th>
-              <th>右左</th>
-              <th>右右</th>
-            </tr>
-            <tr>
-              <td>{{.Hands.Left.Rate | toPer}}</td>
-              <td>{{.Hands.LL.Rate | toPer}}</td>
-              <td>{{.Hands.LR.Rate | toPer}}</td>
-              <td>{{.Hands.RL.Rate | toPer}}</td>
-              <td>{{.Hands.RR.Rate | toPer}}</td>
-            </tr>
-            <tr>
-              <th>右手</th>
-              <th>同指</th>
-              <th>同键</th>
-              <th>小跨排</th>
-              <th>大跨排</th>
-            </tr>
-            <tr>
-              <td>{{.Hands.Right.Rate | toPer}}</td>
-              <td>{{.Fingers.Same.Rate | toPer}}</td>
-              <td>{{.Combs.DoubleHit.Rate | toPer}}</td>
-              <td>{{.Combs.SingleSpan.Rate | toPer}}</td>
-              <td>{{.Combs.MultiSpan.Rate | toPer}}</td>
-            </tr>
-            <tr>
-              <th>当量</th>
-              <th>异手</th>
-              <th>异指</th>
-              <th>错手</th>
-              <th>小指干扰</th>
-            </tr>
-            <tr>
-              <td>{{.Combs.Equivalent | printf "%.3f"}}</td>
-              <td>{{.Hands.Diff.Rate | toPer}}</td>
-              <td>{{.Fingers.Diff.Rate | toPer}}</td>
-              <td>{{.Combs.LongFingersDisturb.Rate | toPer}}</td>
-              <td>{{.Combs.LittleFingersDisturb.Rate | toPer}}</td>
-            </tr>
-          </table>
-        </div>
-
-        <div class="cardBlock stat">
-          <table class="statHead">
-            <tr>
-              <th>码长</th>
-            </tr>
-            <tr>
-              <th>词长</th>
-            </tr>
-            <tr>
-              <th>选重</th>
-            </tr>
-          </table>
-          <div class="statTable">
-            <table>
-              <tr>
-                {{range $k,$v := .CodeLen.Dist}} {{ if ne $v 0 }}
-                <td>{{$k}}:{{$v}}</td>
-                {{end}} {{end}}
-              </tr>
-              <tr>
-                {{range $k,$v := .Words.Dist}}{{ if ne $v 0 }}
-                <td>{{$k}}:{{$v}}</td>
-                {{end}} {{end}}
-              </tr>
-              <tr>
-                {{range $k,$v := .Collision.Dist}}{{ if ne $v 0 }}
-                <td>{{$k}}:{{$v}}</td>
-                {{end}} {{end}}
-              </tr>
-            </table>
-          </div>
-        </div>
-
-        <div class="cardBlock">
-          <div class="keyRateTitle">按键频率 %</div>
-          <table class="heatMap">
-            {{range .KeyHeatMap}}
-            <tr>
-              {{range .}} {{.}}{{end}}
-            </tr>
-            {{end}}
-            <tr class="finHeatMap">
-              {{range .FinHeatMap}} {{.}} {{end}}
-            </tr>
-          </table>
-        </div>
-      </div>
-      {{end}}
-    </div>
-    <div id="footer">
-      <a href="https://github.com/nopdan/gosmq" target="_blank">访问仓库</a>
-    </div>
-  </body>
-</html>
diff --git a/internal/serve/tmpl.go b/internal/serve/tmpl.go
deleted file mode 100644
index 8d7799e..0000000
--- a/internal/serve/tmpl.go
+++ /dev/null
@@ -1,131 +0,0 @@
-package serve
-
-import (
-	"fmt"
-	"html/template"
-	"io"
-	"os"
-	"strings"
-
-	_ "embed"
-
-	"github.com/nopdan/gosmq/pkg/smq"
-)
-
-//go:embed assets/tmpl.html
-var tmpl string
-
-// 赛码结果
-type Result struct {
-	smq.Result
-	KeyHeatMap [][]template.HTML
-	FinHeatMap [10]template.HTML
-}
-
-// 供模版使用的数据
-type TmplData struct {
-	TextName    string
-	TextLen     int
-	NotHanCount int
-	Results     []*Result
-}
-
-// 初始化
-func NewHTML() *TmplData {
-	ret := new(TmplData)
-	return ret
-}
-
-// 添加一个结果
-func (d *TmplData) AddResult(res *smq.Result) {
-
-	if strings.ContainsRune(res.TextName, '《') {
-		d.TextName = res.TextName
-	} else {
-		d.TextName = "《" + res.TextName + "》"
-	}
-	d.TextLen = res.TextLen
-	d.NotHanCount = res.Basic.NotHanCount
-
-	tmp := new(Result)
-	tmp.Result = *res
-
-	tmp.genKeyHeatMap()
-	tmp.genFinHeatMap()
-	d.Results = append(d.Results, tmp)
-}
-
-// 输出 html 文件
-func (d *TmplData) OutputHTMLFile(fileName string) {
-	file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
-	if err != nil {
-		panic(err)
-	}
-	defer file.Close()
-
-	d.OutputHTML(file)
-}
-
-func (d *TmplData) OutputHTML(w io.Writer) {
-	funcMap := template.FuncMap{"toPer": toPercentage}
-	t := template.New("tmpl.html").Funcs(funcMap)
-	_, err := t.Parse(tmpl)
-	if err != nil {
-		panic(err)
-	}
-	t.Execute(w, d)
-}
-
-// float64转换成百分数
-func toPercentage(src float64) string {
-	return fmt.Sprintf("%.2f%%", src*100.0)
-}
-
-// 生成按键热力图
-func (res *Result) genKeyHeatMap() {
-	keys := res.Keys
-	max := 0.07
-	res.KeyHeatMap = make([][]template.HTML, 4)
-	line1 := "1234567890 "
-	line2 := "qwertyuiop "
-	line3 := "asdfghjkl;'"
-	line4 := "zxcvbnm,./ "
-	for j := 0; j < 11; j++ {
-		res.KeyHeatMap[0] = append(res.KeyHeatMap[0], genKeyHeatCode(keys[string(line1[j])], max, line1[j]))
-		res.KeyHeatMap[1] = append(res.KeyHeatMap[1], genKeyHeatCode(keys[string(line2[j])], max, line2[j]))
-		res.KeyHeatMap[2] = append(res.KeyHeatMap[2], genKeyHeatCode(keys[string(line3[j])], max, line3[j]))
-		res.KeyHeatMap[3] = append(res.KeyHeatMap[3], genKeyHeatCode(keys[string(line4[j])], max, line4[j]))
-	}
-}
-
-// 按键颜色代码片段
-func genKeyHeatCode(sk *smq.CountRate, max float64, key byte) template.HTML {
-	if key == ' ' {
-		return template.HTML("")
-	}
-	var freq float64
-	if sk != nil {
-		freq = sk.Rate
-	}
-	return template.HTML(fmt.Sprintf(
-		`<td class="key" style="background-color: rgba(255,0,0,%.4f);">%s <div class="heatMapRate">%.2f</div></td>`,
-		freq/max*0.6, string(key), freq*100))
-}
-
-// 生成手指热力图
-func (res *Result) genFinHeatMap() {
-	src := res.Fingers.Dist
-	max := 0.25
-	fins := []string{"左小", "左无", "左中", "左食", "左拇指", "右拇指", "右食", "右中", "右无", "右小"}
-	for i := 0; i < 9; i++ {
-		res.FinHeatMap[i] = genFinHeatCode(src[i+1].Rate, max, fins[i])
-	}
-	res.FinHeatMap[9] = genFinHeatCode(src[0].Rate, max, fins[9])
-}
-
-// 手指颜色代码片段
-func genFinHeatCode(freq, max float64, fin string) template.HTML {
-	return template.HTML(fmt.Sprintf(
-		`<td class="key fin" style="background-color: rgba(0,0,255,%.4f);">%s <div class="heatMapRate">%.2f</div></td>`,
-		freq/max*0.6, fin, freq*100))
-}
diff --git a/pkg/server/dist/placeholder b/pkg/server/dist/placeholder
deleted file mode 100644
index e69de29..0000000
diff --git a/pkg/server/race.go b/pkg/server/race.go
index 4f723ad..c1bc54d 100644
--- a/pkg/server/race.go
+++ b/pkg/server/race.go
@@ -48,7 +48,7 @@ func (d *Data) Race() []byte {
 		case "local":
 			t.Path = v.Path
 		case "upload":
-			t.Bytes = fileList[v.Index]
+			t.Bytes = files[v.Index]
 		case "clipboard":
 			t.String = v.Text
 		default:
@@ -64,7 +64,7 @@ func (d *Data) Race() []byte {
 		case "local":
 			t.Path = v.Path
 		case "upload":
-			t.Bytes = fileList[v.Index]
+			t.Bytes = files[v.Index]
 		case "clipboard":
 			t.String = v.Text
 		default:
diff --git a/pkg/server/serve.go b/pkg/server/serve.go
deleted file mode 100644
index daf5f3d..0000000
--- a/pkg/server/serve.go
+++ /dev/null
@@ -1,201 +0,0 @@
-package server
-
-import (
-	"encoding/json"
-	"fmt"
-	"io"
-	"io/fs"
-	"log"
-	"net/http"
-	"os"
-	"strconv"
-	"sync"
-	"time"
-)
-
-type Options struct {
-	Text  optText   `json:"text"`
-	Dicts []optDict `json:"dicts"`
-	Web   string    `json:"web"`
-}
-
-type optText struct {
-	Name  string `json:"name"`
-	Plain string `json:"plain"`
-	Path  string `json:"path"`
-	Flag  bool   `json:"flag"` // 手动输入赛文
-}
-
-type optDict struct {
-	Path   string `json:"path"`
-	Single bool   `json:"single"`
-	Space  string `json:"space"`
-	Stable bool   `json:"stable"`
-}
-
-func parseOptions(src []byte) Options {
-	var opt Options
-	if e := json.Unmarshal(src, &opt); e != nil {
-		fmt.Println("...Error in Unmarshal: ", e.Error())
-	}
-	return opt
-}
-
-// func toSmqDict(opt optDict) *smq.Dict {
-// 	dict := &smq.Dict{
-// 		Single:       opt.Single,
-// 		Stable:       opt.Stable,
-// 		PressSpaceBy: opt.Space,
-// 	}
-// 	dict.Load("dict/" + opt.Path)
-// 	fmt.Println("载入码表:", dict.Name)
-// 	return dict
-// }
-
-// var smqRes []*smq.Result
-
-// func GetResultJson(src []byte) []byte {
-// 	var opts = parseOptions(src)
-// 	s := &smq.Text{}
-// 	if opts.Text.Flag {
-// 		if opts.Text.Name == "" {
-// 			opts.Text.Name = "赛文"
-// 		}
-// 		s.LoadString(opts.Text.Name, opts.Text.Plain)
-// 		fmt.Println("载入文本:", opts.Text.Name)
-// 	} else {
-// 		s.Load("text/" + opts.Text.Path)
-// 		fmt.Println("载入文本:", s.Name)
-// 	}
-// 	dicts := make([]*smq.Dict, 0)
-// 	for _, v := range opts.Dicts {
-// 		// opt := toSmqDict(v)
-// 		dicts = append(dicts, toSmqDict(v))
-// 		// s.Add(opt)
-// 	}
-// 	smqRes = s.Race(dicts, false)
-// 	result, _ := json.Marshal(smqRes)
-// 	return result
-// }
-
-func PostHandler(w http.ResponseWriter, r *http.Request) {
-	setHeader(&w)
-	defer r.Body.Close()
-	if r.Method == "POST" {
-		start := time.Now()
-		// body, _ := io.ReadAll(r.Body)
-		// fmt.Println("    post body: ", string(body))
-		// rjson := GetResultJson(body)
-		// w.Write(rjson)
-		// fmt.Println("    returned json: ", string(rjson))
-		fmt.Printf("比赛结束,耗时:%v\n\n", time.Since(start))
-	}
-}
-
-// 递归遍历文件夹
-func getFiles(dirname string, pre string) []string {
-	ret := make([]string, 0)
-
-	fileInfos, err := os.ReadDir(dirname)
-	if err != nil {
-		panic(err)
-	}
-	for _, fi := range fileInfos {
-		if fi.IsDir() {
-			//继续遍历fi这个目录
-			tmp := getFiles(dirname+"/"+fi.Name(), fi.Name()+"/")
-			ret = append(ret, tmp...)
-		} else {
-			ret = append(ret, pre+fi.Name())
-		}
-	}
-	return ret
-}
-
-func Serve2(port string, silent bool) {
-	dist, _ := fs.Sub(dist, "dist")
-	http.Handle("/", http.FileServer(http.FS(dist)))
-	http.HandleFunc("/race", RaceHandler)
-	http.HandleFunc("/upload", UploadHandler)
-	http.HandleFunc("/file_index", IndexHandler)
-	http.HandleFunc("/api", PostHandler)
-	http.HandleFunc("/texts", func(w http.ResponseWriter, r *http.Request) {
-		setHeader(&w)
-		b, _ := json.Marshal(getFiles(`text/`, ""))
-		w.Write(b)
-	})
-	http.HandleFunc("/dicts", func(w http.ResponseWriter, r *http.Request) {
-		setHeader(&w)
-		b, _ := json.Marshal(getFiles(`dict/`, ""))
-		w.Write(b)
-	})
-
-	http.HandleFunc("/result", func(w http.ResponseWriter, r *http.Request) {
-		setHeader(&w)
-		// if len(smqRes) == 0 {
-		// 	return
-		// }
-		// h := NewHTML()
-		// for _, v := range smqRes {
-		// 	h.AddResult(v)
-		// }
-		// h.OutputHTML(w)
-	})
-
-	url := "http://localhost:" + port
-	var wg sync.WaitGroup
-	wg.Add(1)
-	go func() {
-		fmt.Println("Listen and serve: ", url)
-		err := http.ListenAndServe(":"+port, nil)
-		if err != nil {
-			fmt.Println(err)
-			panic("...Server failed.")
-		}
-		wg.Done()
-	}()
-	if !silent {
-		// openBrowser(url)
-	}
-	wg.Wait()
-}
-
-func RaceHandler(w http.ResponseWriter, r *http.Request) {
-	setHeader(&w)
-	text := r.FormValue("text")
-	dict := r.FormValue("dict")
-	fmt.Printf("    text: %v\n    dict: %v\n", text, dict)
-	w.Write([]byte("{\"hello\": \"world\"}"))
-}
-
-var fileList = make([][]byte, 0, 1)
-
-func UploadHandler(w http.ResponseWriter, r *http.Request) {
-	setHeader(&w)
-	r.ParseMultipartForm(1024 * 1024 * 1024) // 最大 1GB
-	fmt.Println(r.Form)
-
-	file, handler, err := r.FormFile("file")
-	if err != nil {
-		log.Printf("err: %v\n", err)
-		return
-	}
-	defer file.Close()
-	log.Printf("POST:%v", handler.Header)
-
-	mbData, err := io.ReadAll(file)
-	if err != nil {
-		log.Printf("err: %v\n", err)
-		return
-	}
-	fileList = append(fileList, mbData)
-	// fmt.Println(string(mbData))
-	index := len(fileList) - 1
-	w.Write([]byte("{'index': " + strconv.Itoa(index) + "}"))
-}
-
-func IndexHandler(w http.ResponseWriter, r *http.Request) {
-	setHeader(&w)
-	index := len(fileList)
-	w.Write([]byte("{\"index\": " + strconv.Itoa(index) + "}"))
-}