Tuesday 24 November 2020

git create branch, merge branch

//create a new repository with new txt file in master
 git add .
git commit -m "1"

[master (root-commit) 9455543] 1
 1 file changed, 1 insertion(+)
 create mode 100644 New Text Document.txt

git remote add origin https://github.com/chuanshuoge6/test.git
git push -u origin master

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 219 bytes | 219.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/chuanshuoge6/test.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
repository master has a txt with abc in it
//create a branch of master
git checkout -b branch1

Switched to a new branch 'branch1'

git push origin branch1

Total 0 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'branch1' on GitHub by visiting:
remote:      https://github.com/chuanshuoge6/test/pull/new/branch1
remote:
To https://github.com/chuanshuoge6/test.git
 * [new branch]      branch1 -> branch1
branch1 created

branch1 has same file as master
//make change on branch1
git add .
git commit -m "2"

[branch1 e32762d] 2
 1 file changed, 2 insertions(+), 1 deletion(-)

git push -u origin branch1

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 251 bytes | 251.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/chuanshuoge6/test.git
   9455543..e32762d  branch1 -> branch1
Branch 'branch1' set up to track remote branch 'branch1' from 'origin'.
branch1 txt file is added a line "bcd"
//switch to master
git checkout master

Switched to branch 'master'
Your branch is up to date with 'origin/master'.

//merge branch1 to master
git merge branch1

Updating 9455543..e32762d
Fast-forward
 New Text Document.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

git push

Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/chuanshuoge6/test.git
   9455543..e32762d  master -> master
master is merged by branch1, master has a new line "bcd" from branch1

//delete branch1
git branch -d branch1

Deleted branch branch1 (was e86d57c).

git push origin :branch1

To https://github.com/chuanshuoge6/test.git
 - [deleted]         branch1
branch1 is removed
reference:


广州市中心

Monday 23 November 2020

golang 24 ionic react upload file to server 2 - upload multiple files in a click

 code link: https://github.com/chuanshuoge6/go-ionic-directory
upload folder empty on server, click upload icon

select multiple files

files uploaded to server

verify on server upload folder
//cmd - server
index post
index post
upload post
Uploaded File: YodaoDict.exe File Size: 268352
Uploaded File: YodaoDict.exe.new File Size: 271936
Uploaded File: YoudaoDict.exe File Size: 5952064
Uploaded File: YoudaoDict.exe.old File Size: 5903936
index post

------------------------------
//go.main
func uploadPostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("upload post")
w.Header().Set("Content-Type", "application/x-msdownload")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)

r.ParseMultipartForm(1000)

files := r.MultipartForm.File["myFile"]
dir := r.PostForm.Get("dir")

for i, header := range files {
file, err := files[i].Open()
if err != nil {
fmt.Println(err)
return
}
defer file.Close()

fmt.Printf("Uploaded File: %+v ", header.Filename)
fmt.Printf("File Size: %+v\n", header.Size)

path := dir + "\\" + header.Filename
resFile, err := os.Create(path)
if err != nil {
fmt.Println(err)
return
}
defer resFile.Close()

io.Copy(resFile, file)

}

json.NewEncoder(w).Encode("ok")
}

---------------------------------------
//folderDisplay.js

import React, { useState } from 'react';
import { folder, folderOpenOutline, documentOutline, cloudUploadOutline, cloudDownloadOutline } from 'ionicons/icons';
import { IonIcon } from '@ionic/react';
import axios from 'axios'
import '../pages/Home.css'
import saveAs from 'file-saver';
const qs = require('querystring')

export default function FolderDisplay(props) {
    const [open, setOpen] = useState(false)
    const [subDir, setSubDir] = useState([])
    const [showLoad, setShowLoad] = useState(false)
    const [downlaodProgress, setDownloadProgress] = useState(0)
    const [uploadProgress, setUploadProgress] = useState(0)

    function post_dir(d) {
        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d })
        })
            .then(response => {
                setSubDir(response.data)
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function download_dir(d, name) {
        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/download/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d }),
            responseType: 'blob',  // important

            onDownloadProgress: progressEvent => {
                const p = parseInt(progressEvent.loaded / props.size * 100);
                setDownloadProgress(p)
            },
        })
            .then(response => {
                console.log(response)
                saveAs(response.data, name);
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function clickEvent() {
        setShowLoad(!showLoad)

        if (!props.isDir) { return }

        if (!open) {
            post_dir(props.dir)
        }

        setOpen(!open)
    }

    function downloadEvent() {
        download_dir(props.dir, props.name)
    }

    function uploadEvent() {
        const inputId = "fileInput" + props.dir
        console.log(inputId)
        document.getElementById(inputId).click()
    }

    function fileChange() {
        const inputId = "fileInput" + props.dir
        const files = document.getElementById(inputId).files
        let i;
        let formdata = new FormData();

        for (i = 0; i < files.length; i++) {
            formdata.append("myFile", files[i]);
        }

        formdata.append("dir", props.dir)

        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/upload/',
            data: formdata,
            onUploadProgress: progressEvent => {
                const p = parseInt(progressEvent.loaded / progressEvent.total * 99);
                setUploadProgress(p)
            },
        })
            .then(res => {
                console.log(res.data);
                if (res.data === 'ok') {
                    setUploadProgress(100)
                }
            })
            .catch((err) => {
                console.log(err)
            })
    }

    const folder_icon = open ? <IonIcon icon={folderOpenOutline} /> : <IonIcon icon={folder} />

    const sub_folder_list = subDir.map((item, index) => {
        const dir_split = item.Name.split("\\")
        const folder_name = dir_split[dir_split.length - 1].replace(props.name, '')
        const dir_name = item.Name.replace(folder_name, '') + '\\' + folder_name
        return <li key={dir_name}>
            <FolderDisplay name={folder_name} dir={dir_name} isDir={item.IsDir} size={item.Size} key={item.Name} />
        </li>
    })

    return (
        <li >
            <span onClick={() => clickEvent()}>
                {props.isDir ? folder_icon : <IonIcon icon={documentOutline} />}{' '}
                {props.name}{' '}
                {showLoad && props.isDir ? <IonIcon icon={cloudUploadOutline} onClick={() => uploadEvent()} /> : null}{' '}
                {showLoad && !props.isDir ? <IonIcon icon={cloudDownloadOutline} onClick={() => downloadEvent()} /> : null}{' '}
                {downlaodProgress != 0 ? downlaodProgress + '%' : null}
                {uploadProgress != 0 ? uploadProgress + '%' : null}
                <input type="file" multiple id={"fileInput" + props.dir} style={{ display: "none" }} onChange={() => fileChange()}></input>
            </span>
            {open ? <ul className="no-bullets">
                {sub_folder_list}
            </ul> : null}
        </li>
    );
};

reference:

go handling multiple file uploads

Sunday 22 November 2020

golang 23 ionic react upload file to server 1

 code link: https://github.com/chuanshuoge6/go-ionic-directory
app shows server directory on phone, static folder is empty
press upload icon

browse for files, select expo-location

upload starts

upload finishes

open static folder again, file is uploaded

upload another file

open folder on server, verify files are uploaded
//cmd - server logs
index get
index post
upload post
Uploaded File: expo-location-6a2380c18118466d88e1dbb510e776b9-signed.apk File Size: 51880840 MIME Header: map[Content-Disposition:[form-data; name="myFile"; filename="expo-location-6a2380c18118466d88e1dbb510e776b9-signed.apk"] Content-Type:[application/vnd.android.package-archive]]
index post
index post
upload post
request Content-Type isn't multipart/form-data
upload post
Uploaded File: expo-forex-771bec8df58843c3a1974f3d932afa85-signed.apk File Size: 53496647 MIME Header: map[Content-Disposition:[form-data; name="myFile"; filename="expo-forex-771bec8df58843c3a1974f3d932afa85-signed.apk"] Content-Type:[application/vnd.android.package-archive]]
index post

//main.go
func uploadPostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("upload post")
w.Header().Set("Content-Type", "application/x-msdownload")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)

r.ParseMultipartForm(1000)

file, handler, err := r.FormFile("myFile")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
fmt.Printf("Uploaded File: %+v ", handler.Filename)
fmt.Printf("File Size: %+v ", handler.Size)
fmt.Printf("MIME Header: %+v\n", handler.Header)

path := rootDir() + "\\golang12\\static\\" + handler.Filename
resFile, err := os.Create(path)
if err != nil {
fmt.Println(err)
return
}
defer resFile.Close()

io.Copy(resFile, file)
json.NewEncoder(w).Encode("ok")
}

---------------------------
//folderDisplay.js
import React, { useState } from 'react';
import { folder, folderOpenOutline, documentOutline, cloudUploadOutline, cloudDownloadOutline } from 'ionicons/icons';
import { IonIcon } from '@ionic/react';
import axios from 'axios'
import '../pages/Home.css'
import saveAs from 'file-saver';
const qs = require('querystring')

export default function FolderDisplay(props) {
    const [open, setOpen] = useState(false)
    const [subDir, setSubDir] = useState([])
    const [showLoad, setShowLoad] = useState(false)
    const [downlaodProgress, setDownloadProgress] = useState(0)
    const [uploadProgress, setUploadProgress] = useState(0)

    function post_dir(d) {
        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d })
        })
            .then(response => {
                setSubDir(response.data)
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function download_dir(d, name) {
        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/download/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d }),
            responseType: 'blob',  // important

            onDownloadProgress: progressEvent => {
                const p = parseInt(progressEvent.loaded / props.size * 100);
                setDownloadProgress(p)
            },
        })
            .then(response => {
                console.log(response)
                saveAs(response.data, name);
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function clickEvent() {
        setShowLoad(!showLoad)

        if (!props.isDir) { return }

        if (!open) {
            post_dir(props.dir)
        }

        setOpen(!open)
    }

    function downloadEvent() {
        download_dir(props.dir, props.name)
    }

    function uploadEvent() {
        const inputId = "fileInput" + props.dir
        console.log(inputId)
        //open file browser
        document.getElementById(inputId).click()
    }

    function fileChange() {
        const inputId = "fileInput" + props.dir
        const file = document.getElementById(inputId).files[0]
        let formdata = new FormData();
        formdata.append("myFile", file);

        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/upload/',
            data: formdata,
            onUploadProgress: progressEvent => {
                const p = parseInt(progressEvent.loaded / progressEvent.total * 99);
                setUploadProgress(p)
            },
        })
            .then(res => {
                console.log(res.data);
                if (res.data === 'ok') {
                    setUploadProgress(100)
                }
            })
            .catch((err) => {
                console.log(err)
            })
    }

    const folder_icon = open ? <IonIcon icon={folderOpenOutline} /> : <IonIcon icon={folder} />

    const sub_folder_list = subDir.map((item, index) => {
        const dir_split = item.Name.split("\\")
        const folder_name = dir_split[dir_split.length - 1].replace(props.name, '')
        const dir_name = item.Name.replace(folder_name, '') + '\\' + folder_name
        return <li key={dir_name}>
            <FolderDisplay name={folder_name} dir={dir_name} isDir={item.IsDir} size={item.Size} key={item.Name} />
        </li>
    })

    return (
        <li >
            <span onClick={() => clickEvent()}>
                {props.isDir ? folder_icon : <IonIcon icon={documentOutline} />}{' '}
                {props.name}{' '}
                {showLoad && props.isDir ? <IonIcon icon={cloudUploadOutline} onClick={() => uploadEvent()} /> : null}{' '}
                {showLoad && !props.isDir ? <IonIcon icon={cloudDownloadOutline} onClick={() => downloadEvent()} /> : null}{' '}
                {downlaodProgress != 0 ? downlaodProgress + '%' : null}
                {uploadProgress != 0 ? uploadProgress + '%' : null}
                <input type="file" id={"fileInput" + props.dir} style={{ display: "none" }} onChange={() => fileChange()}></input>
            </span>
            {open ? <ul className="no-bullets">
                {sub_folder_list}
            </ul> : null}
        </li>
    );
};

Saturday 21 November 2020

西双版纳傣家菜

golang 22 ionic react download file from server

access server directory by phone 
open static folder -> press file name -> press download icon

file starts downloading to phone browser, progress is shown

download complete, file is saved in phone download folder
//main.go
package main

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"path"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"

"github.com/gorilla/mux"
)

type fileStruct struct {
Name  string
IsDir bool
Size  int64
}

var projectPath = rootDir() + "\\golang12\\"

func indexGetHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("index get")
dir := viewDirectory(projectPath)

w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(dir)
}

func indexPostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("index post")
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)

r.ParseForm()
path := r.PostForm.Get("dir")
dir := viewDirectory(path)

json.NewEncoder(w).Encode(dir)
}

func downloadPostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("download post")
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)

r.ParseForm()
dir := r.PostForm.Get("dir")
dirSlash := strings.Replace(dir, "\\", "/", -1)
_, filename := path.Split(dirSlash)

fmt.Println(dir,)
w.Header().Set("Content-Disposition", "attachment; filename="+strconv.Quote(filename))

file, err := os.Open(dir)
if err != nil {
log.Fatal(err)
}
defer file.Close()

fi, err := file.Stat()
if err != nil {
log.Fatal(err)
}

w.Header().Set("Content-Length", strconv.FormatInt(fi.Size(), 10))

io.Copy(w, file)
}

func rootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}

func viewDirectory(dirname string) []fileStruct {
f, err := os.Open(dirname)
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}
files, err := f.Readdir(-1)
f.Close()
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}

var dir = []fileStruct{}
for _, file := range files {
name := dirname + file.Name()
var size int64 = 10000000
if !file.IsDir() {
size = file.Size()
}

dir = append(dir, fileStruct{
Name:  name,
IsDir: file.IsDir(),
Size:  size,
})
}

sort.SliceStable(dir, func(i, j int) bool {
return dir[i].Name < dir[j].Name
})

return dir
}

func main() {
r := mux.NewRouter()
r.HandleFunc("/", indexGetHandler).Methods("GET")
r.HandleFunc("/", indexPostHandler).Methods("POST", "OPTIONS")
r.HandleFunc("/download/", downloadPostHandler).Methods("POST", "OPTIONS")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
http.ListenAndServe(":8000", nil)
}

-----------------------------------
//folderDisplay.js
import React, { useState } from 'react';
import { folder, folderOpenOutline, documentOutline, cloudUploadOutline, cloudDownloadOutline } from 'ionicons/icons';
import { IonIcon } from '@ionic/react';
import axios from 'axios'
import '../pages/Home.css'
import saveAs from 'file-saver';
const qs = require('querystring')

export default function FolderDisplay(props) {
    const [open, setOpen] = useState(false)
    const [subDir, setSubDir] = useState([])
    const [showLoad, setShowLoad] = useState(false)
    const [downlaodProgress, setDownloadProgress] = useState(0)

    function post_dir(d) {
        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d })
        })
            .then(response => {
                setSubDir(response.data)
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function download_dir(d, name) {
        axios({
            method: 'post',
            url: 'http://192.168.0.18:8000/download/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d }),
            responseType: 'blob',  // important

            onDownloadProgress: progressEvent => {
                const p = parseInt(progressEvent.loaded / props.size * 100);
                setDownloadProgress(p)
            },
        })
            .then(response => {
                console.log(response)
                saveAs(response.data, name);
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function clickEvent() {
        setShowLoad(!showLoad)

        if (!props.isDir) { return }

        if (!open) {
            post_dir(props.dir)
        }

        setOpen(!open)
    }

    function downloadEvent() {
        download_dir(props.dir, props.name)
    }

    const folder_icon = open ? <IonIcon icon={folderOpenOutline} /> : <IonIcon icon={folder} />

    const sub_folder_list = subDir.map((item, index) => {
        const dir_split = item.Name.split("\\")
        const folder_name = dir_split[dir_split.length - 1].replace(props.name, '')
        const dir_name = item.Name.replace(folder_name, '') + '\\' + folder_name
        return <li>
            <FolderDisplay name={folder_name} dir={dir_name} isDir={item.IsDir} size={item.Size} />
        </li>
    })

    return (
        <li >
            <span onClick={() => clickEvent()}>
                {props.isDir ? folder_icon : <IonIcon icon={documentOutline} />}{' '}
                {props.name}{' '}
                {showLoad && props.isDir ? <IonIcon icon={cloudUploadOutline} /> : null}{' '}
                {showLoad && !props.isDir ? <IonIcon icon={cloudDownloadOutline} onClick={() => downloadEvent()} /> : null}{' '}
                {downlaodProgress != 0 ? downlaodProgress + '%' : null}
            </span>
            {open ? <ul class="no-bullets">
                {sub_folder_list}
            </ul> : null}
        </li>
    );
};

远征捕鱿记

南海明珠人工岛

Wednesday 18 November 2020

golang 21 ionic react directory tree view

 code linkhttps://github.com/chuanshuoge6/go-ionic-directory
app shows treeview of server directory, click folder to expand or collapse files

//cmd - server log
C:\Users\bob\golang12\directory-app
[{C:\Users\bob\golang12\directory-app.git true} {C:\Users\bob\golang12\directory-app.gitignore false} {C:\Users\bob\golang12\directory-appcapacitor.config.json false} {C:\Users\bob\golang12\directory-appionic.config.json false} {C:\Users\bob\golang12\directory-appnode_modules true} {C:\Users\bob\golang12\directory-apppackage-lock.json false} {C:\Users\bob\golang12\directory-apppackage.json false} {C:\Users\bob\golang12\directory-apppublic true} {C:\Users\bob\golang12\directory-appsrc true} {C:\Users\bob\golang12\directory-apptsconfig.json false}]

//main.go
package main

import (
"encoding/json"
"fmt"
"net/http"
"os"
"path"
"path/filepath"
"runtime"
"sort"

"github.com/gorilla/mux"
)

type fileStruct struct {
Name  string
IsDir bool
}

var projectPath = rootDir() + "\\golang12\\"

func indexGetHandler(w http.ResponseWriter, r *http.Request) {

dir := viewDirectory(projectPath)

w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(dir)
}

func indexPostHandler(w http.ResponseWriter, r *http.Request) {

w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)

r.ParseForm()
fmt.Println(r.PostForm)
path := r.PostForm.Get("dir")
fmt.Println(path)
dir := viewDirectory(path)

json.NewEncoder(w).Encode(dir)
}

func rootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}

func viewDirectory(dirname string) []fileStruct {
f, err := os.Open(dirname)
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}
files, err := f.Readdir(-1)
f.Close()
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}

var dir = []fileStruct{}
for _, file := range files {
name := dirname + file.Name()
dir = append(dir, fileStruct{Name: name, IsDir: file.IsDir()})
}

sort.SliceStable(dir, func(i, j int) bool {
return dir[i].Name < dir[j].Name
})

fmt.Println(dir)

return dir
}

func main() {
r := mux.NewRouter()
r.HandleFunc("/", indexGetHandler).Methods("GET")
r.HandleFunc("/", indexPostHandler).Methods("POST", "OPTIONS")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
http.ListenAndServe(":8000", nil)
}

-----------------------------------------
//directory-app/src/pages/Home.js

import React, { useState, useEffect } from 'react';
import './Home.css';
import axios from 'axios'
import FolderDisplay from '../components/folderDisplay'

export default function Home() {
  const [dir, setDir] = useState([])

  useEffect(() => {
    document.title = 'directory'
    get_dir()
  }, [])

  function get_dir() {
    axios({
      method: 'get',
      url: 'http://localhost:8000/',
    })
      .then(response => {
        setDir(response.data)
      })
      .catch(function (error) {
        alert(error);
        setTimeout(() => {
          get_dir()
        }, 5000);
      });
  }

  return (
    <div style={{ overflowY: 'scroll', height: '100%' }}>
      <h1>Server</h1>
      <ul class="no-bullets">
        {
          dir.map((item, index) => {
            const dir_split = item.Name.split("\\")
            const folder_name = dir_split[dir_split.length - 1]
            return <FolderDisplay name={folder_name} dir={item.Name} isDir={item.IsDir} />
          })
        }
      </ul>
    </div>
  );
};

--------------------------------------
//directory-app/src/components/folderDisplay.js

import React, { useState } from 'react';
import { folder, folderOpenOutline, documentOutline } from 'ionicons/icons';
import { IonIcon } from '@ionic/react';
import axios from 'axios'
import '../pages/Home.css'
const qs = require('querystring')

export default function FolderDisplay(props) {
    const [open, setOpen] = useState(false)
    const [subDir, setSubDir] = useState([])

    function post_dir(d) {
        axios({
            method: 'post',
            url: 'http://localhost:8000/',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            data: qs.stringify({ dir: d })
        })
            .then(response => {
                setSubDir(response.data)
            })
            .catch(function (error) {
                alert(error);
            });
    }

    function clickEvent() {
        if (!props.isDir) { return }

        if (!open) {
            post_dir(props.dir)
        }

        setOpen(!open)
    }

    const folder_icon = open ? <IonIcon icon={folderOpenOutline} /> : <IonIcon icon={folder} />

    const sub_folder_list = subDir.map((item, index) => {
        const dir_split = item.Name.split("\\")
        const folder_name = dir_split[dir_split.length - 1].replace(props.name, '')
        const dir_name = item.Name.replace(folder_name, '') + '\\' + folder_name
        return <li>
            <FolderDisplay name={folder_name} dir={dir_name} isDir={item.IsDir} />
        </li>
    })

    return (
        <li >
            <span onClick={() => clickEvent()}>
                {props.isDir ? folder_icon : <IonIcon icon={documentOutline} />}{' '}
                {props.name}
            </span>
            {open ? <ul class="no-bullets">
                {sub_folder_list}
            </ul> : null}
        </li>
    );
};

----------------------
//directory-app/src/pages/Home.css

ul.no-bullets {
    list-style-type: none;
  }

reference:

go json response

ionic react

go cross-origin

axios post x-www-form-urlencoded

golang20 list the files in a folder

 C:\Users\bob\golang11>go run main.go
a.txt
SSMS-Setup-ENU.exe
w3school.jpg

------------------------
package main

import (
"fmt"
"log"
"os"
"path"
"path/filepath"
"runtime"
)

func rootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}

func main() {
dirname := rootDir() + "\\golang9\\download"

f, err := os.Open(dirname)
if err != nil {
log.Fatal(err)
}
files, err := f.Readdir(-1)
f.Close()
if err != nil {
log.Fatal(err)
}

for _, file := range files {
fmt.Println(file.Name())
}
}

Tuesday 17 November 2020

Great Asian Railway Journeys

golang 19 upload file to server

upload from desktop

upload from phone

file uploaded to upload folder on server
//cmd - server
C:\Users\bob\golang10>go run main.go
Uploaded File: SSMS-Setup-ENU.exe
File Size: 841083616
MIME Header: map[Content-Disposition:[form-data; name="myFile"; filename="SSMS-Setup-ENU.exe"] Content-Type:[application/x-msdownload]]
SSMS-Setup-ENU.exe uploaded

---------------------------------
//main.go
package main

import (
"fmt"
"html/template"
"io"
"net/http"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"

"github.com/gorilla/mux"
)

var templates *template.Template
var uploadPath = rootDir() + "\\golang10\\upload\\"

func indexGetHandler(w http.ResponseWriter, r *http.Request) {

templates.ExecuteTemplate(w, "index.html", nil)
}

func indexPostHandler(w http.ResponseWriter, r *http.Request) {

uploadFile(w, r)
}

func uploadFile(w http.ResponseWriter, r *http.Request) {

r.ParseMultipartForm(1000)

file, handler, err := r.FormFile("myFile")
if err != nil {
fmt.Println("Error Retrieving the File")
fmt.Println(err)
return
}
defer file.Close()
fmt.Printf("Uploaded File: %+v\n", handler.Filename)
fmt.Printf("File Size: %+v\n", handler.Size)
fmt.Printf("MIME Header: %+v\n", handler.Header)

path := uploadPath + handler.Filename
resFile, err := os.Create(path)
if err != nil {
fmt.Println(err)
}
defer resFile.Close()

io.Copy(resFile, file)
fmt.Println(handler.Filename, "uploaded")
}

func rootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}

func open(url string) error {
var cmd string
var args []string

switch runtime.GOOS {
case "windows":
cmd = "cmd"
args = []string{"/c", "start"}
case "darwin":
cmd = "open"
default: // "linux", "freebsd", "openbsd", "netbsd"
cmd = "xdg-open"
}
args = append(args, url)
return exec.Command(cmd, args...).Start()
}

func main() {
templates = template.Must(template.ParseGlob("templates/*.html"))
r := mux.NewRouter()
r.HandleFunc("/", indexGetHandler).Methods("GET")
r.HandleFunc("/", indexPostHandler).Methods("POST")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
//open("http://localhost:8000/")
http.ListenAndServe(":8000", nil)
}

--------------------------
//index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <title>File Upload</title>
</head>

<body>
    <div style="text-align: center;">
        <h1>Upload file to server </h1>
    </div>
    <form id="upload_form" enctype="multipart/form-data" method="post">
        <input type="file" name="myFile" id="myFile" onchange="uploadFile()"><br>
        <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
        <h3 id="status"></h3>
        <p id="loaded_n_total"></p>
    </form>
    <script>
        function _(el) {
            return document.getElementById(el);
        }

        function uploadFile() {
            var file = _("myFile").files[0];
            //alert(file.name + " | " + file.size + " | " + file.type);
            var formdata = new FormData();
            formdata.append("myFile", file);
            var ajax = new XMLHttpRequest();
            ajax.upload.addEventListener("progress", progressHandler, false);
            ajax.addEventListener("load", completeHandler, false);
            ajax.addEventListener("error", errorHandler, false);
            ajax.addEventListener("abort", abortHandler, false);
            ajax.open("POST", "http://192.168.0.18:8000/"); // http://www.developphp.com/video/JavaScript/File-Upload-Progress-Bar-Meter-Tutorial-Ajax-PHP
            //use file_upload_parser.php from above url
            ajax.send(formdata);
        }

        function progressHandler(event) {
            _("loaded_n_total").innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
            var percent = (event.loaded / event.total) * 100;
            _("progressBar").value = Math.round(percent);
            _("status").innerHTML = Math.round(percent) + "% uploaded... please wait";
        }

        function completeHandler(event) {
            _("status").innerHTML = event.target.responseText;
            _("progressBar").value = 0; //wil clear progress bar after successful upload
        }

        function errorHandler(event) {
            _("status").innerHTML = "Upload Failed";
        }

        function abortHandler(event) {
            _("status").innerHTML = "Upload Aborted";
        }
    </script>
</body>

</html>