mirror of https://github.com/mindoc-org/mindoc.git
parent
52f5a44691
commit
359c5dfb10
|
@ -178,7 +178,6 @@ func (c *AccountController) Register() {
|
||||||
member.Email = email
|
member.Email = email
|
||||||
member.Status = 0
|
member.Status = 0
|
||||||
if err := member.Add(); err != nil {
|
if err := member.Add(); err != nil {
|
||||||
beego.Error(err)
|
|
||||||
c.JsonResult(6006, "注册失败,请联系系统管理员处理")
|
c.JsonResult(6006, "注册失败,请联系系统管理员处理")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,6 @@ func (c *ManagerController) ChangeMemberRole() {
|
||||||
member.Role = role
|
member.Role = role
|
||||||
|
|
||||||
if err := member.Update(); err != nil {
|
if err := member.Update(); err != nil {
|
||||||
logs.Error("", err)
|
|
||||||
c.JsonResult(6003, "用户权限设置失败")
|
c.JsonResult(6003, "用户权限设置失败")
|
||||||
}
|
}
|
||||||
member.ResolveRoleName()
|
member.ResolveRoleName()
|
||||||
|
@ -233,8 +232,7 @@ func (c *ManagerController) EditMember() {
|
||||||
member.Password = password
|
member.Password = password
|
||||||
}
|
}
|
||||||
if err := member.Update(); err != nil {
|
if err := member.Update(); err != nil {
|
||||||
beego.Error(err)
|
c.JsonResult(6004, err.Error())
|
||||||
c.JsonResult(6004, "保存失败")
|
|
||||||
}
|
}
|
||||||
c.JsonResult(0, "ok")
|
c.JsonResult(0, "ok")
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
|
|
||||||
type Converter struct {
|
type Converter struct {
|
||||||
BasePath string
|
BasePath string
|
||||||
|
OutputPath string
|
||||||
Config Config
|
Config Config
|
||||||
Debug bool
|
Debug bool
|
||||||
GeneratedCover string
|
GeneratedCover string
|
||||||
|
@ -123,10 +124,9 @@ func (this *Converter) Convert() (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//将当前文件夹下的所有文件压缩成zip包,然后直接改名成content.epub
|
//将当前文件夹下的所有文件压缩成zip包,然后直接改名成content.epub
|
||||||
f := filepath.Join(this.BasePath, "content.epub")
|
f := filepath.Join(this.OutputPath, "content.epub")
|
||||||
fmt.Println("epub目录 " + f)
|
|
||||||
os.Remove(f) //如果原文件存在了,则删除;
|
os.Remove(f) //如果原文件存在了,则删除;
|
||||||
if err = ziptil.Zip(f, this.BasePath); err == nil {
|
if err = ziptil.Zip(this.BasePath,f); err == nil {
|
||||||
//创建导出文件夹
|
//创建导出文件夹
|
||||||
os.Mkdir(this.BasePath+"/"+output, os.ModePerm)
|
os.Mkdir(this.BasePath+"/"+output, os.ModePerm)
|
||||||
if len(this.Config.Format) > 0 {
|
if len(this.Config.Format) > 0 {
|
||||||
|
@ -434,8 +434,8 @@ func (this *Converter) generateContentOpf() (err error) {
|
||||||
//转成epub
|
//转成epub
|
||||||
func (this *Converter) convertToEpub() (err error) {
|
func (this *Converter) convertToEpub() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
filepath.Join(this.BasePath, "content.epub"),
|
filepath.Join(this.OutputPath, "content.epub"),
|
||||||
filepath.Join(this.BasePath, output, "book.epub"),
|
filepath.Join(this.OutputPath, output, "book.epub"),
|
||||||
}
|
}
|
||||||
cmd := exec.Command(ebookConvert, args...)
|
cmd := exec.Command(ebookConvert, args...)
|
||||||
|
|
||||||
|
@ -443,13 +443,15 @@ func (this *Converter) convertToEpub() (err error) {
|
||||||
fmt.Println(cmd.Args)
|
fmt.Println(cmd.Args)
|
||||||
}
|
}
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
|
|
||||||
|
//return filetil.CopyFile(filepath.Join(this.OutputPath, "content.epub"),filepath.Join(this.OutputPath, output, "book.epub"))
|
||||||
}
|
}
|
||||||
|
|
||||||
//转成mobi
|
//转成mobi
|
||||||
func (this *Converter) convertToMobi() (err error) {
|
func (this *Converter) convertToMobi() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
filepath.Join(this.BasePath, "content.epub"),
|
filepath.Join(this.OutputPath, "content.epub"),
|
||||||
filepath.Join(this.BasePath, output, "book.mobi"),
|
filepath.Join(this.OutputPath, output, "book.mobi"),
|
||||||
}
|
}
|
||||||
cmd := exec.Command(ebookConvert, args...)
|
cmd := exec.Command(ebookConvert, args...)
|
||||||
if this.Debug {
|
if this.Debug {
|
||||||
|
@ -462,8 +464,8 @@ func (this *Converter) convertToMobi() (err error) {
|
||||||
//转成pdf
|
//转成pdf
|
||||||
func (this *Converter) convertToPdf() (err error) {
|
func (this *Converter) convertToPdf() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
filepath.Join(this.BasePath, "content.epub"),
|
filepath.Join(this.OutputPath, "content.epub"),
|
||||||
filepath.Join(this.BasePath, output, "book.pdf"),
|
filepath.Join(this.OutputPath, output, "book.pdf"),
|
||||||
}
|
}
|
||||||
//页面大小
|
//页面大小
|
||||||
if len(this.Config.PaperSize) > 0 {
|
if len(this.Config.PaperSize) > 0 {
|
||||||
|
@ -484,16 +486,16 @@ func (this *Converter) convertToPdf() (err error) {
|
||||||
args = append(args, "--pdf-footer-template",this.Config.Footer)
|
args = append(args, "--pdf-footer-template",this.Config.Footer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(this.Config.MarginLeft) > 0 {
|
if strings.Count(this.Config.MarginLeft,"") > 0 {
|
||||||
args = append(args, "--pdf-page-margin-left", this.Config.MarginLeft)
|
args = append(args, "--pdf-page-margin-left", this.Config.MarginLeft)
|
||||||
}
|
}
|
||||||
if len(this.Config.MarginTop) > 0 {
|
if strings.Count(this.Config.MarginTop,"") > 0 {
|
||||||
args = append(args, "--pdf-page-margin-top", this.Config.MarginTop)
|
args = append(args, "--pdf-page-margin-top", this.Config.MarginTop)
|
||||||
}
|
}
|
||||||
if len(this.Config.MarginRight) > 0 {
|
if strings.Count(this.Config.MarginRight,"") > 0 {
|
||||||
args = append(args, "--pdf-page-margin-right", this.Config.MarginRight)
|
args = append(args, "--pdf-page-margin-right", this.Config.MarginRight)
|
||||||
}
|
}
|
||||||
if len(this.Config.MarginBottom) > 0 {
|
if strings.Count(this.Config.MarginBottom,"") > 0 {
|
||||||
args = append(args, "--pdf-page-margin-bottom", this.Config.MarginBottom)
|
args = append(args, "--pdf-page-margin-bottom", this.Config.MarginBottom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,8 +515,8 @@ func (this *Converter) convertToPdf() (err error) {
|
||||||
// 转成word
|
// 转成word
|
||||||
func (this *Converter) convertToDocx() (err error) {
|
func (this *Converter) convertToDocx() (err error) {
|
||||||
args := []string{
|
args := []string{
|
||||||
this.BasePath + "/content.epub",
|
filepath.Join(this.OutputPath , "content.epub"),
|
||||||
this.BasePath + "/" + output + "/book.docx",
|
filepath.Join(this.OutputPath , output , "book.docx"),
|
||||||
}
|
}
|
||||||
args = append(args, "--docx-no-toc")
|
args = append(args, "--docx-no-toc")
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"github.com/lifei6671/mindoc/utils"
|
"github.com/lifei6671/mindoc/utils"
|
||||||
"gopkg.in/russross/blackfriday.v2"
|
"gopkg.in/russross/blackfriday.v2"
|
||||||
"github.com/lifei6671/mindoc/utils/ziptil"
|
"github.com/lifei6671/mindoc/utils/ziptil"
|
||||||
|
"github.com/lifei6671/mindoc/utils/filetil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BookResult struct {
|
type BookResult struct {
|
||||||
|
@ -189,6 +190,7 @@ func (m *BookResult) ToBookResult(book Book) *BookResult {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//导出PDF、word等格式
|
||||||
func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
|
func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
|
||||||
|
|
||||||
convertBookResult := ConvertBookResult{}
|
convertBookResult := ConvertBookResult{}
|
||||||
|
@ -202,7 +204,7 @@ func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
|
||||||
docxpath := filepath.Join(outputPath, "book.docx")
|
docxpath := filepath.Join(outputPath, "book.docx")
|
||||||
|
|
||||||
//先将转换的文件储存到临时目录
|
//先将转换的文件储存到临时目录
|
||||||
tempOutputPath := filepath.Join(os.TempDir(),sessionId) //filepath.Abs(filepath.Join("cache", sessionId))
|
tempOutputPath := filepath.Join(os.TempDir(),sessionId,m.Identify) //filepath.Abs(filepath.Join("cache", sessionId))
|
||||||
|
|
||||||
os.MkdirAll(outputPath, 0766)
|
os.MkdirAll(outputPath, 0766)
|
||||||
os.MkdirAll(tempOutputPath, 0766)
|
os.MkdirAll(tempOutputPath, 0766)
|
||||||
|
@ -332,18 +334,28 @@ func (m *BookResult) Converter(sessionId string) (ConvertBookResult, error) {
|
||||||
f.Close()
|
f.Close()
|
||||||
return convertBookResult, err
|
return convertBookResult, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// html = strings.Replace(html, "<img src=\"/uploads", "<img src=\"" + c.BaseUrl() + "/uploads", -1)
|
|
||||||
|
|
||||||
f.WriteString(html)
|
f.WriteString(html)
|
||||||
f.Close()
|
f.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","css","kancloud.css"),filepath.Join(tempOutputPath,"styles","css","kancloud.css"))
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","css","export.css"),filepath.Join(tempOutputPath,"styles","css","export.css"))
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","editor.md","css","editormd.preview.css"),filepath.Join(tempOutputPath,"styles","editor.md","css","editormd.preview.css"))
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","prettify","themes","prettify.css"),filepath.Join(tempOutputPath,"styles","prettify","themes","prettify.css"))
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","css,","markdown.preview.css"),filepath.Join(tempOutputPath,"styles","css","markdown.preview.css"))
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","highlight","styles","vs.css"),filepath.Join(tempOutputPath,"styles","highlight","styles","vs.css"))
|
||||||
|
filetil.CopyFile(filepath.Join(conf.WorkingDirectory,"static","katex","katex.min.css"),filepath.Join(tempOutputPath,"styles","katex","katex.min.css"))
|
||||||
|
|
||||||
|
|
||||||
eBookConverter := &converter.Converter{
|
eBookConverter := &converter.Converter{
|
||||||
BasePath: tempOutputPath,
|
BasePath: tempOutputPath,
|
||||||
|
OutputPath: strings.TrimSuffix(tempOutputPath,"sources"),
|
||||||
Config: ebookConfig,
|
Config: ebookConfig,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if err := eBookConverter.Convert(); err != nil {
|
if err := eBookConverter.Convert(); err != nil {
|
||||||
beego.Error("转换文件错误:" + m.BookName + " => " + err.Error())
|
beego.Error("转换文件错误:" + m.BookName + " => " + err.Error())
|
||||||
return convertBookResult, err
|
return convertBookResult, err
|
||||||
|
|
|
@ -169,7 +169,8 @@ func (m *Member) Add() error {
|
||||||
hash, err := utils.PasswordHash(m.Password)
|
hash, err := utils.PasswordHash(m.Password)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
beego.Error("加密用户密码失败 =>",err)
|
||||||
|
return errors.New("加密用户密码失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Password = hash
|
m.Password = hash
|
||||||
|
@ -179,7 +180,8 @@ func (m *Member) Add() error {
|
||||||
_, err = o.Insert(m)
|
_, err = o.Insert(m)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
beego.Error("保存用户数据到数据时失败 =>",err)
|
||||||
|
return errors.New("保存用户失败")
|
||||||
}
|
}
|
||||||
m.ResolveRoleName()
|
m.ResolveRoleName()
|
||||||
return nil
|
return nil
|
||||||
|
@ -192,8 +194,12 @@ func (m *Member) Update(cols ...string) error {
|
||||||
if m.Email == "" {
|
if m.Email == "" {
|
||||||
return errors.New("邮箱不能为空")
|
return errors.New("邮箱不能为空")
|
||||||
}
|
}
|
||||||
|
if c, err := o.QueryTable(m.TableNameWithPrefix()).Filter("email", m.Email).Exclude("member_id",m.MemberId).Count(); err == nil && c > 0 {
|
||||||
|
return errors.New("邮箱已被使用")
|
||||||
|
}
|
||||||
if _, err := o.Update(m, cols...); err != nil {
|
if _, err := o.Update(m, cols...); err != nil {
|
||||||
return err
|
beego.Error("保存用户信息失败=>",err)
|
||||||
|
return errors.New("保存用户信息失败")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
body{
|
||||||
|
margin: 5px auto;
|
||||||
|
padding: 5px 30px;
|
||||||
|
}
|
||||||
|
.article-title{
|
||||||
|
margin: 15px auto;
|
||||||
|
line-height: 35px;
|
||||||
|
}
|
||||||
|
.editormd-preview-container{
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ body {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,h2,h3,h4,h5,h6,strong,input,select,textarea,button,body,code {
|
h1,h2,h3,h4,h5,h6,strong,input,select,textarea,button,body,code {
|
||||||
font-family: "Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Microsoft Yahei","Helvetica Neue",Helvetica;
|
font-family: "Helvetica Neue",Helvetica,"Segoe UI",Arial,freesans,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Microsoft Yahei","Helvetica Neue",Helvetica;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright (C) 2015 Google Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Pretty printing styles. Used with prettify.js. */
|
||||||
|
|
||||||
|
|
||||||
|
/* SPAN elements with the classes below are added by prettyprint. */
|
||||||
|
.pln { color: #000 } /* plain text */
|
||||||
|
|
||||||
|
@media screen {
|
||||||
|
.str { color: #080 } /* string content */
|
||||||
|
.kwd { color: #008 } /* a keyword */
|
||||||
|
.com { color: #800 } /* a comment */
|
||||||
|
.typ { color: #606 } /* a type name */
|
||||||
|
.lit { color: #066 } /* a literal value */
|
||||||
|
/* punctuation, lisp open bracket, lisp close bracket */
|
||||||
|
.pun, .opn, .clo { color: #660 }
|
||||||
|
.tag { color: #008 } /* a markup tag name */
|
||||||
|
.atn { color: #606 } /* a markup attribute name */
|
||||||
|
.atv { color: #080 } /* a markup attribute value */
|
||||||
|
.dec, .var { color: #606 } /* a declaration; a variable name */
|
||||||
|
.fun { color: red } /* a function name */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use higher contrast and text-weight for printable form. */
|
||||||
|
@media print, projection {
|
||||||
|
.str { color: #060 }
|
||||||
|
.kwd { color: #006; font-weight: bold }
|
||||||
|
.com { color: #600; font-style: italic }
|
||||||
|
.typ { color: #404; font-weight: bold }
|
||||||
|
.lit { color: #044 }
|
||||||
|
.pun, .opn, .clo { color: #440 }
|
||||||
|
.tag { color: #006; font-weight: bold }
|
||||||
|
.atn { color: #404 }
|
||||||
|
.atv { color: #060 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put a border around prettyprinted code snippets. */
|
||||||
|
pre.prettyprint { padding: 2px; border: 1px solid #888 }
|
||||||
|
|
||||||
|
/* Specify class=linenums on a pre to get line numbering */
|
||||||
|
ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */
|
||||||
|
li.L0,
|
||||||
|
li.L1,
|
||||||
|
li.L2,
|
||||||
|
li.L3,
|
||||||
|
li.L5,
|
||||||
|
li.L6,
|
||||||
|
li.L7,
|
||||||
|
li.L8 { list-style-type: none }
|
||||||
|
/* Alternate shading for lines */
|
||||||
|
li.L1,
|
||||||
|
li.L3,
|
||||||
|
li.L5,
|
||||||
|
li.L7,
|
||||||
|
li.L9 { background: #eee }
|
|
@ -4,6 +4,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"io"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
//==================================
|
//==================================
|
||||||
|
@ -41,3 +43,90 @@ func ScanFiles(dir string) (fl []FileList, err error) {
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//拷贝文件
|
||||||
|
func CopyFile(source string, dst string) (err error) {
|
||||||
|
sourceFile, err := os.Open(source)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer sourceFile.Close()
|
||||||
|
|
||||||
|
_,err = os.Stat(filepath.Dir(dst))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(filepath.Dir(dst),0766)
|
||||||
|
}else{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
destFile, err := os.Create(dst)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer destFile.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(destFile, sourceFile)
|
||||||
|
if err == nil {
|
||||||
|
sourceInfo, err := os.Stat(source)
|
||||||
|
if err != nil {
|
||||||
|
err = os.Chmod(dst, sourceInfo.Mode())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//拷贝目录
|
||||||
|
func CopyDir(source string, dest string) (err error) {
|
||||||
|
|
||||||
|
// get properties of source dir
|
||||||
|
sourceInfo, err := os.Stat(source)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// create dest dir
|
||||||
|
err = os.MkdirAll(dest, sourceInfo.Mode())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
directory, _ := os.Open(source)
|
||||||
|
|
||||||
|
objects, err := directory.Readdir(-1)
|
||||||
|
|
||||||
|
for _, obj := range objects {
|
||||||
|
|
||||||
|
sourceFilePointer := filepath.Join(source , obj.Name())
|
||||||
|
|
||||||
|
destinationFilePointer := filepath.Join(dest, obj.Name())
|
||||||
|
|
||||||
|
if obj.IsDir() {
|
||||||
|
// create sub-directories - recursively
|
||||||
|
err = CopyDir(sourceFilePointer, destinationFilePointer)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// perform copy
|
||||||
|
err = CopyFile(sourceFilePointer, destinationFilePointer)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func RemoveDir(dir string) error {
|
||||||
|
return os.RemoveAll(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,11 @@ package ziptil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
"errors"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"fmt"
|
||||||
"github.com/lifei6671/mindoc/utils/filetil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//解压zip文件
|
//解压zip文件
|
||||||
|
@ -47,66 +44,122 @@ func Unzip(zipFile, dest string) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//压缩指定文件或文件夹
|
//压缩文件
|
||||||
//@param dest 压缩后的zip文件目标,如/usr/local/hello.zip
|
func Zip(source, target string) error {
|
||||||
//@param filepath 需要压缩的文件或者文件夹
|
zipFile, err := os.Create(target)
|
||||||
//@return err 错误。如果返回错误,则会删除dest文件
|
|
||||||
func Zip(dest string, filepath ...string) (err error) {
|
|
||||||
if len(filepath) == 0 {
|
|
||||||
return errors.New("lack of file")
|
|
||||||
}
|
|
||||||
//创建文件
|
|
||||||
fzip, err := os.Create(dest)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer fzip.Close()
|
defer zipFile.Close()
|
||||||
|
|
||||||
var filelist []filetil.FileList
|
archive := zip.NewWriter(zipFile)
|
||||||
for _, file := range filepath {
|
defer archive.Close()
|
||||||
if info, err := os.Stat(file); err == nil {
|
source = strings.Replace(source, "\\", "/", -1)
|
||||||
if info.IsDir() { //目录,则扫描文件
|
|
||||||
if f, _ := filetil.ScanFiles(file); len(f) > 0 {
|
filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
|
||||||
filelist = append(filelist, f...)
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
} else { //文件
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
filelist = append(filelist, filetil.FileList{
|
|
||||||
IsDir: false,
|
if path == source {
|
||||||
Name: info.Name(),
|
return nil
|
||||||
Path: file,
|
}
|
||||||
|
header, err := zip.FileInfoHeader(info)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
header.Name = strings.TrimPrefix(strings.TrimPrefix(strings.Replace(path, "\\", "/", -1), source), "/")
|
||||||
|
fmt.Println(header.Name)
|
||||||
|
|
||||||
|
if info.IsDir() {
|
||||||
|
header.Name += "/"
|
||||||
|
} else {
|
||||||
|
header.Method = zip.Deflate
|
||||||
|
}
|
||||||
|
|
||||||
|
writer, err := archive.CreateHeader(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
_, err = io.Copy(writer, file)
|
||||||
|
return err
|
||||||
})
|
})
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
return err
|
||||||
}
|
|
||||||
}
|
|
||||||
w := zip.NewWriter(fzip)
|
|
||||||
defer w.Close()
|
|
||||||
for _, file := range filelist {
|
|
||||||
if !file.IsDir {
|
|
||||||
if fw, err := w.Create(strings.TrimLeft(file.Path, "./")); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
if fileContent, err := ioutil.ReadFile(file.Path); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
if _, err = fw.Write(fileContent); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Compress(dst string,src string) (err error) {
|
////压缩指定文件或文件夹
|
||||||
|
////@param dest 压缩后的zip文件目标,如/usr/local/hello.zip
|
||||||
|
////@param filepath 需要压缩的文件或者文件夹
|
||||||
|
////@return err 错误。如果返回错误,则会删除dest文件
|
||||||
|
//func Zip(dest string, filepath ...string) (err error) {
|
||||||
|
// if len(filepath) == 0 {
|
||||||
|
// return errors.New("lack of file")
|
||||||
|
// }
|
||||||
|
// //创建文件
|
||||||
|
// fzip, err := os.Create(dest)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// defer fzip.Close()
|
||||||
|
//
|
||||||
|
// var filelist []filetil.FileList
|
||||||
|
// for _, file := range filepath {
|
||||||
|
// if info, err := os.Stat(file); err == nil {
|
||||||
|
// if info.IsDir() { //目录,则扫描文件
|
||||||
|
// if f, _ := filetil.ScanFiles(file); len(f) > 0 {
|
||||||
|
// filelist = append(filelist, f...)
|
||||||
|
// }
|
||||||
|
// } else { //文件
|
||||||
|
// filelist = append(filelist, filetil.FileList{
|
||||||
|
// IsDir: false,
|
||||||
|
// Name: info.Name(),
|
||||||
|
// Path: file,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// w := zip.NewWriter(fzip)
|
||||||
|
// defer w.Close()
|
||||||
|
// for _, file := range filelist {
|
||||||
|
// if !file.IsDir {
|
||||||
|
// if fw, err := w.Create(strings.TrimLeft(file.Path, "./")); err != nil {
|
||||||
|
// return err
|
||||||
|
// } else {
|
||||||
|
// if fileContent, err := ioutil.ReadFile(file.Path); err != nil {
|
||||||
|
// return err
|
||||||
|
// } else {
|
||||||
|
// if _, err = fw.Write(fileContent); err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
//}
|
||||||
|
|
||||||
|
func Compress(dst string, src string) (err error) {
|
||||||
d, _ := os.Create(dst)
|
d, _ := os.Create(dst)
|
||||||
defer d.Close()
|
defer d.Close()
|
||||||
w := zip.NewWriter(d)
|
w := zip.NewWriter(d)
|
||||||
defer w.Close()
|
defer w.Close()
|
||||||
|
|
||||||
src = strings.Replace(src,"\\","/",-1)
|
src = strings.Replace(src, "\\", "/", -1)
|
||||||
f, err := os.Open(src)
|
f, err := os.Open(src)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -124,7 +177,6 @@ func Compress(dst string,src string) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func compress(file *os.File, prefix string, zw *zip.Writer) error {
|
func compress(file *os.File, prefix string, zw *zip.Writer) error {
|
||||||
info, err := file.Stat()
|
info, err := file.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -133,7 +185,7 @@ func compress(file *os.File, prefix string, zw *zip.Writer) error {
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
if prefix != "" {
|
if prefix != "" {
|
||||||
prefix = prefix + "/" + info.Name()
|
prefix = prefix + "/" + info.Name()
|
||||||
}else{
|
} else {
|
||||||
prefix = info.Name()
|
prefix = info.Name()
|
||||||
}
|
}
|
||||||
fileInfos, err := file.Readdir(-1)
|
fileInfos, err := file.Readdir(-1)
|
||||||
|
@ -171,9 +223,3 @@ func compress(file *os.File, prefix string, zw *zip.Writer) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
<link href="{{cdncss "/static/css/jstree.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/css/jstree.css"}}" rel="stylesheet">
|
||||||
{{if eq .Model.Editor "markdown"}}
|
{{if eq .Model.Editor "markdown"}}
|
||||||
<link href="{{cdncss "/static/editor.md/css/editormd.preview.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/editor.md/css/editormd.preview.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/prettify/themes/atelier-estuary-dark.min.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/prettify/themes/prettify.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/css/markdown.preview.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/css/markdown.preview.css"}}" rel="stylesheet">
|
||||||
{{else}}
|
{{else}}
|
||||||
<link href="{{cdncss "/static/highlight/styles/zenburn.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/highlight/styles/vs.css"}}" rel="stylesheet">
|
||||||
{{end}}
|
{{end}}
|
||||||
<link href="{{cdncss "/static/katex/katex.min.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/katex/katex.min.css"}}" rel="stylesheet">
|
||||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||||
|
|
|
@ -1,41 +1,23 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8"/>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
|
||||||
|
|
||||||
<title>{{.Model.BookName}} - Powered by MinDoc</title>
|
<title>{{.Model.BookName}} - Powered by MinDoc</title>
|
||||||
|
<link href="styles/css/kancloud.css" rel="stylesheet">
|
||||||
<!-- Bootstrap -->
|
<link href="styles/editor.md/css/editormd.preview.css" rel="stylesheet"/>
|
||||||
<link href="{{.BaseUrl}}/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
<link href="styles/prettify/themes/prettify.css" rel="stylesheet"/>
|
||||||
<link href="{{.BaseUrl}}/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
|
<link href="styles/css/markdown.preview.css" rel="stylesheet"/>
|
||||||
<link href="{{.BaseUrl}}/static/jstree/3.3.4/themes/default/style.min.css" rel="stylesheet">
|
<link href="styles/highlight/styles/vs.css" rel="stylesheet"/>
|
||||||
|
<link href="styles/katex/katex.min.css" rel="stylesheet"/>
|
||||||
<link href="{{.BaseUrl}}/static/nprogress/nprogress.css" rel="stylesheet">
|
<link href="styles/css/export.css" rel="stylesheet"/>
|
||||||
<link href="{{.BaseUrl}}/static/css/kancloud.css" rel="stylesheet">
|
|
||||||
<link href="{{.BaseUrl}}/static/css/jstree.css" rel="stylesheet">
|
|
||||||
{{if eq .Model.Editor "markdown"}}
|
|
||||||
<link href="{{.BaseUrl}}/static/editor.md/css/editormd.preview.css" rel="stylesheet">
|
|
||||||
<link href="{{.BaseUrl}}/static/prettify/themes/atelier-estuary-dark.min.css" rel="stylesheet">
|
|
||||||
<link href="{{.BaseUrl}}/static/css/markdown.preview.css" rel="stylesheet">
|
|
||||||
{{else}}
|
|
||||||
<link href="{{.BaseUrl}}/static/highlight/styles/zenburn.css" rel="stylesheet">
|
|
||||||
{{end}}
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
<div class="m-manual manual-reader">
|
|
||||||
<div class="container-fluid manual-body">
|
|
||||||
|
|
||||||
<div class="manual-article">
|
<body>
|
||||||
<div class="article-content">
|
<h1 class="article-title">{{.Lists.DocumentName}}</h1>
|
||||||
<h1 id="article-title">{{.Lists.DocumentName}}</h1>
|
<div class="article-body markdown-body editormd-preview-container" id="page-content">
|
||||||
<div class="article-body {{if eq $.Model.Editor "markdown"}}markdown-body editormd-preview-container{{else}}editor-content{{end}}" id="page-content">
|
|
||||||
{{str2html .Lists.Release}}
|
{{str2html .Lists.Release}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -27,10 +27,10 @@
|
||||||
<link href="{{cdncss "/static/editor.md/css/editormd.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/editor.md/css/editormd.css"}}" rel="stylesheet">
|
||||||
|
|
||||||
<link href="{{cdncss "/static/css/jstree.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/css/jstree.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/highlight/styles/zenburn.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/highlight/styles/vs.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/webuploader/webuploader.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/webuploader/webuploader.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/css/markdown.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/css/markdown.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/prettify/themes/atelier-estuary-dark.min.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/prettify/themes/prettify.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/css/markdown.preview.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/css/markdown.preview.css"}}" rel="stylesheet">
|
||||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||||
|
|
Loading…
Reference in New Issue