mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve gcompress/gres for packing files
This commit is contained in:
@ -11,11 +11,11 @@ func main() {
|
||||
gres.Dump()
|
||||
|
||||
v := g.View()
|
||||
v.SetPath("/template/layout1")
|
||||
v.SetPath("files/template/layout1")
|
||||
|
||||
s := g.Server()
|
||||
s.SetIndexFolder(true)
|
||||
s.SetServerRoot("/root")
|
||||
s.SetServerRoot("files/root")
|
||||
s.BindHandler("/template", func(r *ghttp.Request) {
|
||||
r.Response.WriteTpl("layout.html")
|
||||
})
|
||||
|
||||
@ -12,7 +12,7 @@ func main() {
|
||||
g.Config().SetFileName("my.ini")
|
||||
g.Dump(g.Config().Get("redis"))
|
||||
|
||||
g.Config().SetPath("/config-custom")
|
||||
g.Config().SetPath("config-custom")
|
||||
g.Config().SetFileName("my.ini")
|
||||
g.Dump(g.Config().Get("redis"))
|
||||
|
||||
|
||||
@ -1,14 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/os/gres"
|
||||
_ "github.com/gogf/gf/os/gres/testdata"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gres.Dump()
|
||||
g.Dump(gres.ScanDir("/root/image", "*"))
|
||||
//file := gres.Get("www")
|
||||
//fmt.Println(file.Open())
|
||||
//g.Dump(gres.ScanDir("/root/image", "*"))
|
||||
//g.Dump(gres.Scan("/root/image/", "*", true))
|
||||
//g.Dump(gres.Scan("/template", "*"))
|
||||
//g.Dump(gres.Scan("/template/layout2", "*.html", true))
|
||||
|
||||
@ -12,7 +12,7 @@ func main() {
|
||||
gres.Dump()
|
||||
|
||||
v := g.View()
|
||||
v.SetPath("/template/layout1")
|
||||
v.SetPath("files/template/layout1")
|
||||
s, err := v.Parse("layout.html")
|
||||
fmt.Println(err)
|
||||
fmt.Println(s)
|
||||
|
||||
@ -12,7 +12,7 @@ func main() {
|
||||
gres.Dump()
|
||||
|
||||
v := g.View()
|
||||
v.SetPath("/template/layout2")
|
||||
v.SetPath("files/template/layout2")
|
||||
s, err := v.Parse("layout.html", g.Map{
|
||||
"mainTpl": "main/main1.html",
|
||||
})
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
package gset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/internal/rwmutex"
|
||||
@ -324,3 +325,8 @@ func (set *Set) Pops(size int) []interface{} {
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func (set *Set) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(set.Slice())
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
package gset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/internal/rwmutex"
|
||||
@ -318,3 +319,8 @@ func (set *IntSet) Pops(size int) []int {
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func (set *IntSet) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(set.Slice())
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
package gset
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/internal/rwmutex"
|
||||
@ -319,3 +320,8 @@ func (set *StringSet) Pops(size int) []string {
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
// MarshalJSON implements the interface MarshalJSON for json.Marshal.
|
||||
func (set *StringSet) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(set.Slice())
|
||||
}
|
||||
|
||||
@ -13,56 +13,90 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/internal/fileinfo"
|
||||
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
)
|
||||
|
||||
// ZipPath compresses <path> to <dest> using zip compressing algorithm.
|
||||
// ZipPath compresses <paths> to <dest> using zip compressing algorithm.
|
||||
// The unnecessary parameter <prefix> indicates the path prefix for zip file.
|
||||
func ZipPath(path, dest string, prefix ...string) error {
|
||||
//
|
||||
// Note that parameter <paths> supports multiple paths join with ','.
|
||||
func ZipPath(paths, dest string, prefix ...string) error {
|
||||
writer, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer writer.Close()
|
||||
return ZipPathWriter(path, writer, prefix...)
|
||||
return ZipPathWriter(paths, writer, prefix...)
|
||||
}
|
||||
|
||||
// ZipPathWriter compresses <path> to <writer> using zip compressing algorithm.
|
||||
// ZipPathWriter compresses <paths> to <writer> using zip compressing algorithm.
|
||||
// The unnecessary parameter <prefix> indicates the path prefix for zip file.
|
||||
func ZipPathWriter(path string, writer io.Writer, prefix ...string) error {
|
||||
//
|
||||
// Note that parameter <paths> supports multiple paths join with ','.
|
||||
func ZipPathWriter(paths string, writer io.Writer, prefix ...string) error {
|
||||
zipWriter := zip.NewWriter(writer)
|
||||
defer zipWriter.Close()
|
||||
for _, path := range strings.Split(paths, ",") {
|
||||
path = strings.TrimSpace(path)
|
||||
if err := doZipPathWriter(path, zipWriter, prefix...); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func doZipPathWriter(path string, zipWriter *zip.Writer, prefix ...string) error {
|
||||
realPath, err := gfile.Search(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zipWriter := zip.NewWriter(writer)
|
||||
defer zipWriter.Close()
|
||||
files, err := gfile.ScanDir(path, "*", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
headerPrefix := ""
|
||||
if len(prefix) > 0 {
|
||||
if len(prefix) > 0 && prefix[0] != "" {
|
||||
headerPrefix = prefix[0]
|
||||
}
|
||||
headerPrefix = strings.Trim(headerPrefix, "\\/")
|
||||
// If path is a directory, add it to the zip prefix.
|
||||
if gfile.IsDir(realPath) {
|
||||
headerPrefix = headerPrefix + "/" + gfile.Basename(realPath)
|
||||
headerPrefix = strings.TrimRight(headerPrefix, "\\/")
|
||||
if gfile.IsDir(path) {
|
||||
if len(headerPrefix) > 0 {
|
||||
headerPrefix += "/"
|
||||
}
|
||||
headerPrefix = headerPrefix + gfile.Basename(path)
|
||||
}
|
||||
headerPrefix = strings.Replace(headerPrefix, "//", "/", -1)
|
||||
for _, file := range files {
|
||||
err := zipFile(file, headerPrefix+gfile.Dir(file[len(realPath):]), zipWriter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Add prefix to zip archive.
|
||||
path = headerPrefix
|
||||
for {
|
||||
err := zipFileVirtual(fileinfo.New(gfile.Basename(path), 0, os.ModeDir, time.Now()), path, zipWriter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if path == "/" || !strings.Contains(path, "/") {
|
||||
break
|
||||
}
|
||||
path = gfile.Dir(path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnZipFile decompresses <archive> to <dest> using zip compressing algorithm.
|
||||
// The parameter <path> specifies the unzipped path of <archive>,
|
||||
// which can be used to specify part of the archive file to unzip.
|
||||
//
|
||||
// Note thate the parameter <dest> should be a directory.
|
||||
func UnZipFile(archive, dest string, path ...string) error {
|
||||
readerCloser, err := zip.OpenReader(archive)
|
||||
if err != nil {
|
||||
@ -75,6 +109,8 @@ func UnZipFile(archive, dest string, path ...string) error {
|
||||
// UnZipContent decompresses <data> to <dest> using zip compressing algorithm.
|
||||
// The parameter <path> specifies the unzipped path of <archive>,
|
||||
// which can be used to specify part of the archive file to unzip.
|
||||
//
|
||||
// Note thate the parameter <dest> should be a directory.
|
||||
func UnZipContent(data []byte, dest string, path ...string) error {
|
||||
reader, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
@ -144,17 +180,10 @@ func zipFile(path string, prefix string, zw *zip.Writer) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
header, err := createFileHeader(info, prefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(prefix) > 0 {
|
||||
prefix = strings.Replace(prefix, `\`, `/`, -1)
|
||||
prefix = strings.TrimRight(prefix, `/`)
|
||||
header.Name = prefix + `/` + header.Name
|
||||
} else {
|
||||
header.Name = header.Name
|
||||
}
|
||||
writer, err := zw.CreateHeader(header)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -166,3 +195,28 @@ func zipFile(path string, prefix string, zw *zip.Writer) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func zipFileVirtual(info os.FileInfo, path string, zw *zip.Writer) error {
|
||||
header, err := createFileHeader(info, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
header.Name = path
|
||||
if _, err := zw.CreateHeader(header); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createFileHeader(info os.FileInfo, prefix string) (*zip.FileHeader, error) {
|
||||
header, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(prefix) > 0 {
|
||||
prefix = strings.Replace(prefix, `\`, `/`, -1)
|
||||
prefix = strings.TrimRight(prefix, `/`)
|
||||
header.Name = prefix + `/` + header.Name
|
||||
}
|
||||
return header, nil
|
||||
}
|
||||
|
||||
53
internal/fileinfo/fileinfo.go
Normal file
53
internal/fileinfo/fileinfo.go
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the MIT License.
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package fileinfo provides virtual os.FileInfo for given information.
|
||||
package fileinfo
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Info struct {
|
||||
name string
|
||||
size int64
|
||||
mode os.FileMode
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
func New(name string, size int64, mode os.FileMode, modTime time.Time) *Info {
|
||||
return &Info{
|
||||
name: name,
|
||||
size: size,
|
||||
mode: mode,
|
||||
modTime: modTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Info) Name() string {
|
||||
return i.name
|
||||
}
|
||||
|
||||
func (i *Info) Size() int64 {
|
||||
return i.size
|
||||
}
|
||||
|
||||
func (i *Info) IsDir() bool {
|
||||
return i.mode.IsDir()
|
||||
}
|
||||
|
||||
func (i *Info) Mode() os.FileMode {
|
||||
return i.mode
|
||||
}
|
||||
|
||||
func (i *Info) ModTime() time.Time {
|
||||
return i.modTime
|
||||
}
|
||||
|
||||
func (i *Info) Sys() interface{} {
|
||||
return nil
|
||||
}
|
||||
@ -38,6 +38,10 @@ type Config struct {
|
||||
vc *gtype.Bool // Whether do violence check in value index searching. It affects the performance when set true(false in default).
|
||||
}
|
||||
|
||||
var (
|
||||
resourceTryFiles = []string{"", "/", "config/", "config", "/config", "/config/"}
|
||||
)
|
||||
|
||||
// New returns a new configuration management object.
|
||||
// The parameter <file> specifies the default configuration file name for reading.
|
||||
func New(file ...string) *Config {
|
||||
@ -257,7 +261,7 @@ func (c *Config) FilePath(file ...string) (path string) {
|
||||
c.paths.RLockFunc(func(array []string) {
|
||||
for _, prefix := range array {
|
||||
// Firstly checking the resource manager.
|
||||
for _, v := range []string{"/", "/config", "/config/"} {
|
||||
for _, v := range resourceTryFiles {
|
||||
if file := gres.Get(prefix + v + name); file != nil {
|
||||
path = file.Name()
|
||||
return
|
||||
@ -274,7 +278,7 @@ func (c *Config) FilePath(file ...string) (path string) {
|
||||
})
|
||||
// Checking the configuration file in default paths.
|
||||
if path == "" && !gres.IsEmpty() {
|
||||
for _, v := range []string{"", "/", "/config", "/config/"} {
|
||||
for _, v := range resourceTryFiles {
|
||||
if file := gres.Get(v + name); file != nil {
|
||||
path = file.Name()
|
||||
return
|
||||
|
||||
@ -29,34 +29,44 @@ func init() {
|
||||
`
|
||||
)
|
||||
|
||||
// Pack packs the path specified by <srcPath> into bytes.
|
||||
// Pack packs the path specified by <srcPaths> into bytes.
|
||||
// The unnecessary parameter <keyPrefix> indicates the prefix for each file
|
||||
// packed into the result bytes.
|
||||
func Pack(srcPath string, keyPrefix ...string) ([]byte, error) {
|
||||
//
|
||||
// Note that parameter <srcPaths> supports multiple paths join with ','.
|
||||
func Pack(srcPaths string, keyPrefix ...string) ([]byte, error) {
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
err := gcompress.ZipPathWriter(srcPath, buffer, keyPrefix...)
|
||||
headerPrefix := ""
|
||||
if len(keyPrefix) > 0 && keyPrefix[0] != "" {
|
||||
headerPrefix = keyPrefix[0]
|
||||
}
|
||||
err := gcompress.ZipPathWriter(srcPaths, buffer, headerPrefix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buffer.Bytes(), nil
|
||||
}
|
||||
|
||||
// PackToFile packs the path specified by <srcPath> to target file <dstPath>.
|
||||
// PackToFile packs the path specified by <srcPaths> to target file <dstPath>.
|
||||
// The unnecessary parameter <keyPrefix> indicates the prefix for each file
|
||||
// packed into the result bytes.
|
||||
func PackToFile(srcPath, dstPath string, keyPrefix ...string) error {
|
||||
data, err := Pack(srcPath, keyPrefix...)
|
||||
//
|
||||
// Note that parameter <srcPaths> supports multiple paths join with ','.
|
||||
func PackToFile(srcPaths, dstPath string, keyPrefix ...string) error {
|
||||
data, err := Pack(srcPaths, keyPrefix...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gfile.PutBytes(dstPath, data)
|
||||
}
|
||||
|
||||
// PackToGoFile packs the path specified by <srcPath> to target go file <goFilePath>
|
||||
// PackToGoFile packs the path specified by <srcPaths> to target go file <goFilePath>
|
||||
// with given package name <pkgName>.
|
||||
//
|
||||
// The unnecessary parameter <keyPrefix> indicates the prefix for each file
|
||||
// packed into the result bytes.
|
||||
//
|
||||
// Note that parameter <srcPaths> supports multiple paths join with ','.
|
||||
func PackToGoFile(srcPath, goFilePath, pkgName string, keyPrefix ...string) error {
|
||||
data, err := Pack(srcPath, keyPrefix...)
|
||||
if err != nil {
|
||||
|
||||
@ -8,11 +8,12 @@ package gres
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
|
||||
"github.com/gogf/gf/container/gtree"
|
||||
"github.com/gogf/gf/os/gfile"
|
||||
)
|
||||
|
||||
@ -14,7 +14,7 @@ import (
|
||||
"github.com/gogf/gf/test/gtest"
|
||||
)
|
||||
|
||||
func Test_Export(t *testing.T) {
|
||||
func Test_Pack(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
srcPath := gdebug.CallerDirectory() + "/testdata/files"
|
||||
goFilePath := gdebug.CallerDirectory() + "/testdata/testdata.go"
|
||||
@ -23,3 +23,23 @@ func Test_Export(t *testing.T) {
|
||||
gtest.Assert(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_PackWithPrefix1(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
srcPath := gdebug.CallerDirectory() + "/testdata/files"
|
||||
goFilePath := gdebug.CallerDirectory() + "/testdata/testdata.go"
|
||||
pkgName := "testdata"
|
||||
err := gres.PackToGoFile(srcPath, goFilePath, pkgName, "www/gf-site/test")
|
||||
gtest.Assert(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_PackWithPrefix2(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
srcPath := gdebug.CallerDirectory() + "/testdata/files"
|
||||
goFilePath := gdebug.CallerDirectory() + "/testdata/testdata.go"
|
||||
pkgName := "testdata"
|
||||
err := gres.PackToGoFile(srcPath, goFilePath, pkgName, "/var/www/gf-site/test")
|
||||
gtest.Assert(err, nil)
|
||||
})
|
||||
}
|
||||
|
||||
2
os/gres/testdata/testdata.go
vendored
2
os/gres/testdata/testdata.go
vendored
File diff suppressed because one or more lines are too long
@ -38,7 +38,8 @@ const (
|
||||
var (
|
||||
// Templates cache map for template folder.
|
||||
// TODO Note that there's no expiring logic for this map.
|
||||
templates = gmap.NewStrAnyMap(true)
|
||||
templates = gmap.NewStrAnyMap(true)
|
||||
resourceTryFiles = []string{"template/", "template", "/template", "/template/"}
|
||||
)
|
||||
|
||||
// getTemplate returns the template object associated with given template folder <path>.
|
||||
@ -116,7 +117,7 @@ func (view *View) searchFile(file string) (path string, folder string, err error
|
||||
}
|
||||
// Checking the configuration file in default paths.
|
||||
if path == "" && !gres.IsEmpty() {
|
||||
for _, v := range []string{"/template", "/template/"} {
|
||||
for _, v := range resourceTryFiles {
|
||||
if file := gres.Get(v + file); file != nil {
|
||||
path = file.Name()
|
||||
folder = gfile.Dir(path)
|
||||
|
||||
Reference in New Issue
Block a user