fmt all go file
This commit is contained in:
1 parent
cba69444a8
commit
7809d00787
100 files changed
+3375
-3331
No files matched your search
+3
-3
@@ -2,8 +2,8 @@ package lea
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/revel/revel"
|
||||
"fmt"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
func Log(i interface{}) {
|
||||
@@ -11,7 +11,7 @@ func Log(i interface{}) {
|
||||
}
|
||||
|
||||
func LogJ(i interface{}) {
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
revel.INFO.Println(string(b))
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ func L(i interface{}) {
|
||||
}
|
||||
|
||||
func LJ(i interface{}) {
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
b, _ := json.MarshalIndent(i, "", " ")
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
+13
-11
@@ -1,10 +1,11 @@
|
||||
package lea
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"net/smtp"
|
||||
"strings"
|
||||
"github.com/revel/revel"
|
||||
)
|
||||
|
||||
// 发送邮件
|
||||
var host = "smtp.ym.163.com"
|
||||
var port = "25"
|
||||
@@ -12,7 +13,7 @@ var username = "noreply@leanote.com"
|
||||
var password = "---"
|
||||
|
||||
func InitEmail() {
|
||||
config := revel.Config;
|
||||
config := revel.Config
|
||||
host, _ = config.String("email.host")
|
||||
port, _ = config.String("email.port")
|
||||
username, _ = config.String("email.username")
|
||||
@@ -56,26 +57,27 @@ var bodyTpl = `
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
func SendEmailOld(to, subject, body string) bool {
|
||||
hp := strings.Split(host, ":")
|
||||
auth := smtp.PlainAuth("", username, password, hp[0])
|
||||
|
||||
|
||||
var content_type string
|
||||
|
||||
|
||||
mailtype := "html"
|
||||
if mailtype == "html" {
|
||||
content_type = "Content-Type: text/"+ mailtype + "; charset=UTF-8"
|
||||
} else{
|
||||
content_type = "Content-Type: text/" + mailtype + "; charset=UTF-8"
|
||||
} else {
|
||||
content_type = "Content-Type: text/plain" + "; charset=UTF-8"
|
||||
}
|
||||
|
||||
|
||||
//body = strings.Replace(bodyTpl, "$body", body, 1)
|
||||
//body = strings.Replace(body, "$title", title, 1)
|
||||
|
||||
msg := []byte("To: " + to + "\r\nFrom: " + username + "<"+ username +">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
||||
msg := []byte("To: " + to + "\r\nFrom: " + username + "<" + username + ">\r\nSubject: " + subject + "\r\n" + content_type + "\r\n\r\n" + body)
|
||||
send_to := strings.Split(to, ";")
|
||||
err := smtp.SendMail(host+":"+port, auth, username, send_to, msg)
|
||||
|
||||
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return false
|
||||
@@ -85,5 +87,5 @@ func SendEmailOld(to, subject, body string) bool {
|
||||
|
||||
func SendToLeanoteOld(subject, title, body string) {
|
||||
to := "leanote@leanote.com"
|
||||
SendEmailOld(to, subject, body);
|
||||
}
|
||||
SendEmailOld(to, subject, body)
|
||||
}
|
||||
+2
-2
@@ -116,13 +116,13 @@ func CopyDir(source string, dest string) (err error) {
|
||||
// create sub-directories - recursively
|
||||
err = CopyDir(sourcefilepointer, destinationfilepointer)
|
||||
if err != nil {
|
||||
// fmt.Println(err)
|
||||
// fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
// perform copy
|
||||
_, err = CopyFile(sourcefilepointer, destinationfilepointer)
|
||||
if err != nil {
|
||||
// fmt.Println(err)
|
||||
// fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -16,7 +16,7 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
transPath = path
|
||||
wand.Genesis()
|
||||
defer wand.Terminus()
|
||||
|
||||
|
||||
w := wand.NewMagickWand()
|
||||
defer w.Destroy()
|
||||
|
||||
@@ -24,7 +24,7 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
width := w.ImageWidth()
|
||||
height := w.ImageHeight()
|
||||
if maxWidth != 0 {
|
||||
@@ -34,14 +34,14 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
width = maxWidth
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
w.SetImageFormat("GIF");
|
||||
|
||||
if err := paint.Thumbnail(w, width, height); err != nil {
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 判断是否是gif图片, 是就不用转换了
|
||||
baseName, ext := SplitFilename(path)
|
||||
var toPath string
|
||||
@@ -50,19 +50,19 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
} else {
|
||||
toPath = TransferExt(path, ".gif");
|
||||
}
|
||||
|
||||
|
||||
if err := w.WriteImage(toPath); err != nil {
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if afterDelete {
|
||||
os.Remove(path)
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
transPath = toPath
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPat
|
||||
func Reset(path string, maxWidth uint) (ok bool, transPath string){
|
||||
wand.Genesis()
|
||||
defer wand.Terminus()
|
||||
|
||||
|
||||
w := wand.NewMagickWand()
|
||||
defer w.Destroy()
|
||||
|
||||
@@ -79,7 +79,7 @@ func Reset(path string, maxWidth uint) (ok bool, transPath string){
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
width := w.ImageWidth()
|
||||
height := w.ImageHeight()
|
||||
if maxWidth != 0 {
|
||||
@@ -93,20 +93,20 @@ func Reset(path string, maxWidth uint) (ok bool, transPath string){
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
toPath := TransferExt(path, ".gif");
|
||||
if err := w.WriteImage(toPath); err != nil {
|
||||
fmt.Println(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
transPath = toPath
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func TransToGif(path string, maxWidth uint, afterDelete bool) (ok bool, transPath string) {
|
||||
return ok, path
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -7,7 +7,7 @@ func ComparePwd(rawPwd, dbPwd string) bool {
|
||||
if len(dbPwd) == 32 {
|
||||
return Md5(rawPwd) == dbPwd
|
||||
}
|
||||
|
||||
|
||||
hex := []byte(dbPwd)
|
||||
return CompareHash(hex, rawPwd)
|
||||
}
|
||||
@@ -19,4 +19,4 @@ func GenPwd(rawPwd string) string {
|
||||
return ""
|
||||
}
|
||||
return string(digest)
|
||||
}
|
||||
}
|
||||
+29
-29
@@ -1,19 +1,19 @@
|
||||
package lea
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"time"
|
||||
"strings"
|
||||
"fmt"
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
"bytes"
|
||||
math_rand "math/rand"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
"io"
|
||||
math_rand "math/rand"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 字符串
|
||||
@@ -31,14 +31,14 @@ func Digest3(str string) string {
|
||||
for _, k := range str {
|
||||
b += k
|
||||
}
|
||||
return fmt.Sprintf("%d", b % 1000)
|
||||
return fmt.Sprintf("%d", b%1000)
|
||||
}
|
||||
func Digest2(str string) string {
|
||||
var b rune = 0
|
||||
for _, k := range str {
|
||||
b += k
|
||||
}
|
||||
return fmt.Sprintf("%d", b % 100)
|
||||
return fmt.Sprintf("%d", b%100)
|
||||
}
|
||||
|
||||
// Guid
|
||||
@@ -77,7 +77,7 @@ func Substr(str string, start, length int) string {
|
||||
func substr(str string, start, length int, isRune bool) string {
|
||||
rs := []rune(str)
|
||||
rs2 := []byte(str)
|
||||
|
||||
|
||||
rl := len(rs)
|
||||
if !isRune {
|
||||
rl = len(rs2)
|
||||
@@ -161,7 +161,7 @@ func SubStringHTMLToRaw(param string, length int) string {
|
||||
continue
|
||||
} else if temp == '>' {
|
||||
isCode = false
|
||||
resultRune[n] = ' ';
|
||||
resultRune[n] = ' '
|
||||
|
||||
n++
|
||||
if n >= length {
|
||||
@@ -170,7 +170,7 @@ func SubStringHTMLToRaw(param string, length int) string {
|
||||
continue
|
||||
}
|
||||
if !isCode {
|
||||
resultRune[n] = temp;
|
||||
resultRune[n] = temp
|
||||
// s += string(temp)
|
||||
n++
|
||||
if n >= length {
|
||||
@@ -192,13 +192,13 @@ func fixHtml(result string) string {
|
||||
|
||||
// 把<div class=xxx的class=xxx去掉
|
||||
tempResult = ReplaceAll(tempResult, "<(/?[a-zA-Z]+)[^<>]*>", "<$1>")
|
||||
|
||||
|
||||
// 3 只能用正则,+stack来去有结束的
|
||||
// golang的正则暂不支持back reference, 以后可以用它来去掉重复的标签
|
||||
p, _ := regexp.Compile("<(/?[a-zA-Z]+)[^<>]*>") // 得到所有的<div>, </div>...
|
||||
strs := p.FindAllString(tempResult, -1)
|
||||
|
||||
// fmt.Println(strs)
|
||||
// fmt.Println(strs)
|
||||
stack := make([]string, len(strs))
|
||||
stackP := -1
|
||||
for _, each := range strs {
|
||||
@@ -215,14 +215,14 @@ func fixHtml(result string) string {
|
||||
// 补全tag
|
||||
if stackP != -1 {
|
||||
fmt.Println(stack[0 : stackP+1])
|
||||
|
||||
|
||||
for _, each := range stack[0 : stackP+1] {
|
||||
if each[1] != '/' {
|
||||
result += "</" + each[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -241,10 +241,10 @@ func SubStringHTML(param string, length int, end string) string {
|
||||
} else {
|
||||
// 1
|
||||
n := 0
|
||||
var temp rune // 中文问题, 用rune来解决
|
||||
var temp rune // 中文问题, 用rune来解决
|
||||
isCode := false //是不是HTML代码
|
||||
isHTML := false //是不是HTML特殊字符,如
|
||||
var i = 0;
|
||||
var i = 0
|
||||
for ; i < lenStr; i++ {
|
||||
temp = rStr[i]
|
||||
if temp == '<' {
|
||||
@@ -281,11 +281,11 @@ func SubStringHTML(param string, length int, end string) string {
|
||||
html, _ := dom.Html()
|
||||
html = strings.Replace(html, "<html><head></head><body>", "", 1)
|
||||
html = strings.Replace(html, "</body></html>", "", 1)
|
||||
|
||||
|
||||
// TODO 把style="float: left"去掉
|
||||
return html
|
||||
|
||||
// 如果有错误, 则使用自己的方法补全, 有风险
|
||||
|
||||
// 如果有错误, 则使用自己的方法补全, 有风险
|
||||
} else {
|
||||
return fixHtml(result)
|
||||
}
|
||||
@@ -305,7 +305,7 @@ func IsGoodPwd(pwd string) (bool, string) {
|
||||
// 是否是email
|
||||
func IsEmail(email string) bool {
|
||||
if email == "" {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
ok, _ := regexp.MatchString(`^([a-zA-Z0-9]+[_|\_|\.|\-]?)*[_a-z\-A-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.|\-]?)*[a-zA-Z0-9\-]+\.[0-9a-zA-Z]{2,6}$`, email)
|
||||
return ok
|
||||
@@ -314,7 +314,7 @@ func IsEmail(email string) bool {
|
||||
// 是否只包含数字, 字母 -, _
|
||||
func IsUsername(username string) bool {
|
||||
if username == "" {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
ok, _ := regexp.MatchString(`[^0-9a-zA-Z_\-]`, username)
|
||||
return !ok
|
||||
@@ -351,15 +351,15 @@ func RandomPwd(num int) string {
|
||||
chars[j] = byte(i)
|
||||
j++
|
||||
}
|
||||
j--;
|
||||
|
||||
j--
|
||||
|
||||
str := ""
|
||||
math_rand.Seed(time.Now().UnixNano())
|
||||
for i := 0; i < num; i++ {
|
||||
x := math_rand.Intn(j)
|
||||
str += string(chars[x])
|
||||
}
|
||||
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
@@ -379,14 +379,14 @@ func InArray(arr []string, str string) bool {
|
||||
func FixFilename(filename string) string {
|
||||
if filename != "" {
|
||||
// 把特殊字段给替换掉
|
||||
// str := `life "%&()+,/:;<>=?@\|`
|
||||
// str := `life "%&()+,/:;<>=?@\|`
|
||||
// . == \\.
|
||||
// $ === \\$
|
||||
reg, _ := regexp.Compile("\\.|/|#|\\$|!|\\^|\\*|'| |\"|%|&|\\(|\\)|\\+|\\,|/|:|;|<|>|=|\\?|@|\\||\\\\")
|
||||
filename = reg.ReplaceAllString(filename, "-")
|
||||
filename = strings.Trim(filename, "-") // 左右单独的-去掉
|
||||
// 把空格替换成-
|
||||
// filename = strings.Replace(filename, " ", "-", -1)
|
||||
// filename = strings.Replace(filename, " ", "-", -1)
|
||||
for strings.Index(filename, "--") >= 0 { // 防止出现连续的--
|
||||
filename = strings.Replace(filename, "--", "-", -1)
|
||||
}
|
||||
|
||||
+21
-21
@@ -2,8 +2,8 @@ package lea
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"regexp"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 验证
|
||||
@@ -38,15 +38,15 @@ var rulesStr = `{
|
||||
`
|
||||
var rulesMap map[string][]map[string]string
|
||||
|
||||
var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
"required": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
var rules = map[string]func(string, map[string]string) (bool, string){
|
||||
"required": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
},
|
||||
"minLength": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"minLength": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -55,7 +55,7 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = len(value) >= dataI
|
||||
return
|
||||
},
|
||||
"min": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"min": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -65,8 +65,8 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = vI >= dataI
|
||||
return
|
||||
},
|
||||
|
||||
"sortField": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
|
||||
"sortField": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -74,22 +74,22 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok = InArray(sortFields, value)
|
||||
return
|
||||
},
|
||||
|
||||
"password": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
|
||||
"password": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
ok = len(value) >= 6
|
||||
return
|
||||
},
|
||||
"email": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"email": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
ok = IsEmail(value)
|
||||
return
|
||||
},
|
||||
"noSpecialChars": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"noSpecialChars": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
@@ -97,8 +97,8 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
return
|
||||
},
|
||||
// www.baidu.com
|
||||
//
|
||||
"domain": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
//
|
||||
"domain": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
ok = true
|
||||
return // 可为空
|
||||
@@ -106,16 +106,16 @@ var rules = map[string]func(string, map[string]string)(bool, string) {
|
||||
ok2, _ := regexp.MatchString(`[^0-9a-zA-Z_\.\-]`, value)
|
||||
ok = !ok2
|
||||
if !ok {
|
||||
return
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
},
|
||||
// abcd
|
||||
"subDomain": func(value string, rule map[string]string)(ok bool, msg string) {
|
||||
"subDomain": func(value string, rule map[string]string) (ok bool, msg string) {
|
||||
if value == "" {
|
||||
ok = true
|
||||
return // 可为空
|
||||
return // 可为空
|
||||
}
|
||||
if len(value) < 4 {
|
||||
ok = false
|
||||
@@ -137,7 +137,7 @@ func InitVd() {
|
||||
|
||||
func Vd(name, value string) (ok bool, msg string) {
|
||||
rs, _ := rulesMap[name]
|
||||
|
||||
|
||||
for _, rule := range rs {
|
||||
ruleFunc, _ := rules[rule["rule"]]
|
||||
if ok2, msg2 := ruleFunc(value, rule); !ok2 {
|
||||
@@ -151,11 +151,11 @@ func Vd(name, value string) (ok bool, msg string) {
|
||||
if msgData != "" {
|
||||
msg += "-" + msgData
|
||||
}
|
||||
return
|
||||
return
|
||||
}
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
}
|
||||
|
||||
func Vds(m map[string]string) (ok bool, msg string) {
|
||||
@@ -166,5 +166,5 @@ func Vds(m map[string]string) (ok bool, msg string) {
|
||||
}
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
return
|
||||
}
|
||||
+176
-176
@@ -1,12 +1,12 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// main functions shows how to TarGz a directory/file and
|
||||
@@ -16,66 +16,66 @@ import (
|
||||
|
||||
func main() {
|
||||
/*
|
||||
os.Mkdir("/home/ty4z2008/tar", 0777)
|
||||
w, err := CopyFile("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/src/1.pdf")
|
||||
//targetfile,sourcefile
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
fmt.Println(w)
|
||||
os.Mkdir("/home/ty4z2008/tar", 0777)
|
||||
w, err := CopyFile("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/src/1.pdf")
|
||||
//targetfile,sourcefile
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
fmt.Println(w)
|
||||
|
||||
TarGz("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/test.tar.gz") //压缩
|
||||
//UnTarGz("/home/ty4z2008/1.tar.gz", "/home/ty4z2008") //解压
|
||||
os.RemoveAll("/home/ty4z2008/tar")
|
||||
*/
|
||||
// TaZip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.tar.gz")
|
||||
Zip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.zip")
|
||||
fmt.Println("ok")
|
||||
TarGz("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/test.tar.gz") //压缩
|
||||
//UnTarGz("/home/ty4z2008/1.tar.gz", "/home/ty4z2008") //解压
|
||||
os.RemoveAll("/home/ty4z2008/tar")
|
||||
*/
|
||||
// TaZip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.tar.gz")
|
||||
Zip("/Users/life/Desktop/j", "/Users/life/Desktop/aaa.zip")
|
||||
fmt.Println("ok")
|
||||
}
|
||||
|
||||
func TarGz(srcDirPath string, destFilePath string) (ok bool) {
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
}
|
||||
|
||||
|
||||
}()
|
||||
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
// Gzip writer
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
// Tar writer
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
// Gzip writer
|
||||
gw := gzip.NewWriter(fw)
|
||||
defer gw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
tarGzDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
tarGzFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
// Tar writer
|
||||
tw := tar.NewWriter(gw)
|
||||
defer tw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
tarGzDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
tarGzFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// Deal with directories
|
||||
@@ -83,148 +83,148 @@ func TarGz(srcDirPath string, destFilePath string) (ok bool) {
|
||||
// Every recurrence append the base path to the recPath
|
||||
// recPath is the path inside of tar.gz
|
||||
func tarGzDir(srcDirPath string, recPath string, tw *tar.Writer) {
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
tarGzDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
tarGzDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
|
||||
tarGzFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
tarGzFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with files
|
||||
func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) {
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
// if last character of header name is '/' it also can be directory
|
||||
// but if you don't set Typeflag, error will occur when you untargz
|
||||
hdr.Name = recPath // + "/"
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Typeflag = tar.TypeDir
|
||||
// hdr.Size = 0
|
||||
//hdr.Mode = 0755 | c_ISDIR
|
||||
// hdr.Mode = int64(fi.Mode()) // 加这个会有错误!!!
|
||||
// hdr.ModTime = fi.ModTime() // 加这个会有错误!!
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
// if last character of header name is '/' it also can be directory
|
||||
// but if you don't set Typeflag, error will occur when you untargz
|
||||
hdr.Name = recPath // + "/"
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Typeflag = tar.TypeDir
|
||||
// hdr.Size = 0
|
||||
//hdr.Mode = 0755 | c_ISDIR
|
||||
// hdr.Mode = int64(fi.Mode()) // 加这个会有错误!!!
|
||||
// hdr.ModTime = fi.ModTime() // 加这个会有错误!!
|
||||
|
||||
// Write hander
|
||||
err := tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
// Write hander
|
||||
err := tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
hdr.Name = recPath
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Size = fi.Size()
|
||||
hdr.Mode = int64(fi.Mode())
|
||||
hdr.ModTime = fi.ModTime()
|
||||
// Create tar header
|
||||
hdr := new(tar.Header)
|
||||
hdr.Name = recPath
|
||||
// fmt.Println(hdr.Name)
|
||||
hdr.Size = fi.Size()
|
||||
hdr.Mode = int64(fi.Mode())
|
||||
hdr.ModTime = fi.ModTime()
|
||||
|
||||
// Write hander
|
||||
err = tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write hander
|
||||
err = tw.WriteHeader(hdr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Write file data
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(tw, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ungzip and untar from source file to destination directory
|
||||
// you need check file exist before you call this function
|
||||
func UnTarGz(srcFilePath string, destDirPath string) {
|
||||
// fmt.Println("UnTarGzing " + srcFilePath + "...")
|
||||
// Create destination directory
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
// fmt.Println("UnTarGzing " + srcFilePath + "...")
|
||||
// Create destination directory
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
|
||||
fr, err := os.Open(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
fr, err := os.Open(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Gzip reader
|
||||
gr, err := gzip.NewReader(fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer gr.Close()
|
||||
// Gzip reader
|
||||
gr, err := gzip.NewReader(fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer gr.Close()
|
||||
|
||||
// Tar reader
|
||||
tr := tar.NewReader(gr)
|
||||
// Tar reader
|
||||
tr := tar.NewReader(gr)
|
||||
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// End of tar archive
|
||||
break
|
||||
}
|
||||
//handleError(err)
|
||||
// fmt.Println("UnTarGzing file..." + hdr.Name)
|
||||
// Check if it is diretory or file
|
||||
if hdr.Typeflag != tar.TypeDir {
|
||||
// Get files from archive
|
||||
// Create diretory before create file
|
||||
os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name), os.ModePerm)
|
||||
// Write data to file
|
||||
fw, _ := os.Create(destDirPath + "/" + hdr.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, tr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fmt.Println("Well done!")
|
||||
for {
|
||||
hdr, err := tr.Next()
|
||||
if err == io.EOF {
|
||||
// End of tar archive
|
||||
break
|
||||
}
|
||||
//handleError(err)
|
||||
// fmt.Println("UnTarGzing file..." + hdr.Name)
|
||||
// Check if it is diretory or file
|
||||
if hdr.Typeflag != tar.TypeDir {
|
||||
// Get files from archive
|
||||
// Create diretory before create file
|
||||
os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name), os.ModePerm)
|
||||
// Write data to file
|
||||
fw, _ := os.Create(destDirPath + "/" + hdr.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, tr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// fmt.Println("Well done!")
|
||||
}
|
||||
|
||||
// Copyfile
|
||||
func CopyFile(dstName, srcName string) (written int64, err error) {
|
||||
src, err := os.Open(srcName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
src, err := os.Open(srcName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer src.Close()
|
||||
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer dst.Close()
|
||||
return io.Copy(dst, src)
|
||||
}
|
||||
+117
-117
@@ -1,12 +1,12 @@
|
||||
package archive
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// main functions shows how to TarGz a directory/file and
|
||||
@@ -15,43 +15,43 @@ import (
|
||||
// you need check file exist before you call this function
|
||||
|
||||
func Zip(srcDirPath string, destFilePath string) (ok bool) {
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
fw, err := os.Create(destFilePath)
|
||||
|
||||
// Tar writer
|
||||
tw := zip.NewWriter(fw)
|
||||
defer tw.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
zipDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
zipFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
// Tar writer
|
||||
tw := zip.NewWriter(fw)
|
||||
defer tw.Close()
|
||||
|
||||
// Check if it's a file or a directory
|
||||
f, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fi, err := f.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if fi.IsDir() {
|
||||
// handle source directory
|
||||
// fmt.Println("Cerating tar.gz from directory...")
|
||||
zipDir(srcDirPath, path.Base(srcDirPath), tw)
|
||||
} else {
|
||||
// handle file directly
|
||||
// fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
|
||||
zipFile(srcDirPath, fi.Name(), tw, fi)
|
||||
}
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// Deal with directories
|
||||
@@ -59,69 +59,69 @@ func Zip(srcDirPath string, destFilePath string) (ok bool) {
|
||||
// Every recurrence append the base path to the recPath
|
||||
// recPath is the path inside of tar.gz
|
||||
func zipDir(srcDirPath string, recPath string, tw *zip.Writer) {
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
// Open source diretory
|
||||
dir, err := os.Open(srcDirPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
zipDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
// Get file info slice
|
||||
fis, err := dir.Readdir(0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, fi := range fis {
|
||||
// Append path
|
||||
curPath := srcDirPath + "/" + fi.Name()
|
||||
// Check it is directory or file
|
||||
if fi.IsDir() {
|
||||
// Directory
|
||||
// (Directory won't add unitl all subfiles are added)
|
||||
// fmt.Printf("Adding path...%s\n", curPath)
|
||||
zipDir(curPath, recPath+"/"+fi.Name(), tw)
|
||||
} else {
|
||||
// File
|
||||
// fmt.Printf("Adding file...%s\n", curPath)
|
||||
}
|
||||
|
||||
zipFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
zipFile(curPath, recPath+"/"+fi.Name(), tw, fi)
|
||||
}
|
||||
}
|
||||
|
||||
// Deal with files
|
||||
func zipFile(srcFile string, recPath string, tw *zip.Writer, fi os.FileInfo) {
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
/*
|
||||
fh, err := zip.FileInfoHeader(fi)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fh.Name = recPath // + "/"
|
||||
err = tw.WriteHeader(hdr)
|
||||
tw.Create(recPath)
|
||||
*/
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
if fi.IsDir() {
|
||||
// fmt.Println("??")
|
||||
// Create tar header
|
||||
/*
|
||||
fh, err := zip.FileInfoHeader(fi)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fh.Name = recPath // + "/"
|
||||
err = tw.WriteHeader(hdr)
|
||||
tw.Create(recPath)
|
||||
*/
|
||||
} else {
|
||||
// File reader
|
||||
fr, err := os.Open(srcFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
// Write hander
|
||||
w, err2 := tw.Create(recPath)
|
||||
if err2 != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(w, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// Write hander
|
||||
w, err2 := tw.Create(recPath)
|
||||
if err2 != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write file data
|
||||
_, err = io.Copy(w, fr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ungzip and untar from source file to destination directory
|
||||
@@ -129,33 +129,33 @@ func zipFile(srcFile string, recPath string, tw *zip.Writer, fi os.FileInfo) {
|
||||
func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
|
||||
ok = false
|
||||
msg = ""
|
||||
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
|
||||
defer func() { //必须要先声明defer,否则不能捕获到panic异常
|
||||
if err := recover(); err != nil {
|
||||
msg = fmt.Sprintf("%v", err)
|
||||
ok = false
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
os.Mkdir(destDirPath, os.ModePerm)
|
||||
r, err := zip.OpenReader(srcFilePath);
|
||||
r, err := zip.OpenReader(srcFilePath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer r.Close();
|
||||
defer r.Close()
|
||||
for _, f := range r.File {
|
||||
// fmt.Println("FileName : ", f.Name); // j/aaa.zip
|
||||
rc, err := f.Open();
|
||||
if err!=nil {
|
||||
// fmt.Println("FileName : ", f.Name); // j/aaa.zip
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
// 把首文件夹去掉, 即j去掉, 分离出文件夹和文件名
|
||||
paths := strings.Split(f.Name, "/")
|
||||
prePath := ""
|
||||
filename := ""
|
||||
l := len(paths)
|
||||
// fmt.Println(l)
|
||||
// fmt.Println(l)
|
||||
if l > 1 {
|
||||
// 去掉第1个文件夹
|
||||
if l == 2 {
|
||||
@@ -167,26 +167,26 @@ func Unzip(srcFilePath string, destDirPath string) (ok bool, msg string) {
|
||||
} else {
|
||||
filename = f.Name
|
||||
}
|
||||
// fmt.Println(prePath)
|
||||
|
||||
// fmt.Println(prePath)
|
||||
|
||||
// 相对于目标文件件下的路径
|
||||
destPath := destDirPath + "/" + filename
|
||||
destPath := destDirPath + "/" + filename
|
||||
if prePath != "" {
|
||||
os.MkdirAll(destDirPath + "/" + prePath, os.ModePerm)
|
||||
os.MkdirAll(destDirPath+"/"+prePath, os.ModePerm)
|
||||
destPath = destDirPath + "/" + prePath + "/" + filename
|
||||
}
|
||||
// Write data to file
|
||||
// fmt.Println(destPath)
|
||||
fw, _ := os.Create(destPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, rc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Write data to file
|
||||
// fmt.Println(destPath)
|
||||
fw, _ := os.Create(destPath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = io.Copy(fw, rc)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
}
|
||||
+34
-33
@@ -1,10 +1,10 @@
|
||||
package binder
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/leanote/leanote/app/controllers"
|
||||
// "github.com/leanote/leanote/app/controllers/api"
|
||||
"github.com/leanote/leanote/app/info"
|
||||
"github.com/revel/revel"
|
||||
// "github.com/leanote/leanote/app/controllers/api"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
// leanote binder struct
|
||||
// rewrite revel struct binder
|
||||
// not need the struct name as prefix,
|
||||
// not need the struct name as prefix,
|
||||
// eg:
|
||||
// type Note struct {Name}
|
||||
// func (c Controller) List(note Note) revel.Result {}
|
||||
@@ -34,13 +34,13 @@ var MSSBinder = revel.Binder{
|
||||
}
|
||||
return result
|
||||
},
|
||||
|
||||
|
||||
Unbind: func(output map[string]string, name string, val interface{}) {
|
||||
mapValue := reflect.ValueOf(val)
|
||||
for _, key := range mapValue.MapKeys() {
|
||||
revel.Unbind(output, fmt.Sprintf("%v", key.Interface()),
|
||||
mapValue.MapIndex(key).Interface())
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -54,55 +54,56 @@ func nextKey(key string) string {
|
||||
}
|
||||
return key[:fieldLen]
|
||||
}
|
||||
|
||||
var leanoteStructBinder = revel.Binder{
|
||||
// name == "noteOrContent"
|
||||
Bind: func(params *revel.Params, name string, typ reflect.Type) reflect.Value {
|
||||
result := reflect.New(typ).Elem() // 创建一个该类型的, 然后其field从所有的param去取
|
||||
fieldValues := make(map[string]reflect.Value)
|
||||
// fmt.Println(name)
|
||||
// fmt.Println(name)
|
||||
// fmt.Println(typ) // api.NoteFiles
|
||||
// name = files[0], files[1], noteContent
|
||||
// fmt.Println(params.Values)
|
||||
// fmt.Println(params.Values)
|
||||
/*
|
||||
map[Title:[test1] METHOD:[POST] NotebookId:[54c4f51705fcd14031000002]
|
||||
files[1][FileId]:[]
|
||||
controller:[note]
|
||||
files[1][LocalFileId]:[54c7ae27d98d0329dd000000] files[1][HasBody]:[true] files[0][FileId]:[] files[0][LocalFileId]:[54c7ae855e94ea2dba000000] action:[addNote] Content:[<p>lifedddddd</p><p><img src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" alt="" data-mce-src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" style="display: block; margin-left: auto; margin-right: auto;"></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae27d98d0329dd000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImg?fileId=54c7ae27d98d0329dd000000"></p><p><br></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" style="display: block; margin-left: auto; margin-right: auto;"></p><p><br></p><p><br></p>] IsBlog:[false] token:[user1]
|
||||
files[0][HasBody]:[true]]
|
||||
map[Title:[test1] METHOD:[POST] NotebookId:[54c4f51705fcd14031000002]
|
||||
files[1][FileId]:[]
|
||||
controller:[note]
|
||||
files[1][LocalFileId]:[54c7ae27d98d0329dd000000] files[1][HasBody]:[true] files[0][FileId]:[] files[0][LocalFileId]:[54c7ae855e94ea2dba000000] action:[addNote] Content:[<p>lifedddddd</p><p><img src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" alt="" data-mce-src="app://leanote/data/54bdc65599c37b0da9000002/images/1422368307147_2.png" style="display: block; margin-left: auto; margin-right: auto;"></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae27d98d0329dd000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImg?fileId=54c7ae27d98d0329dd000000"></p><p><br></p><p><img src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" alt="" data-mce-src="http://127.0.0.1:8008/api/file/getImage?fileId=54c7ae855e94ea2dba000000" style="display: block; margin-left: auto; margin-right: auto;"></p><p><br></p><p><br></p>] IsBlog:[false] token:[user1]
|
||||
files[0][HasBody]:[true]]
|
||||
*/
|
||||
nameIsSlice := strings.Contains(name, "[")
|
||||
// fmt.Println(params.Values["files[1]"])
|
||||
// fmt.Println(params.Values["Title"])
|
||||
for key, _ := range params.Values {// Title, Content, Files
|
||||
// fmt.Println(params.Values["files[1]"])
|
||||
// fmt.Println(params.Values["Title"])
|
||||
for key, _ := range params.Values { // Title, Content, Files
|
||||
// 这里, 如果没有点, 默认就是a.
|
||||
// life
|
||||
// fmt.Println("key:" + key); // files[0][LocalFileId]
|
||||
// fmt.Println("name:" + name); // files[0][LocalFileId]
|
||||
// fmt.Println("key:" + key); // files[0][LocalFileId]
|
||||
// fmt.Println("name:" + name); // files[0][LocalFileId]
|
||||
var suffix string
|
||||
var noPrefix = false
|
||||
if nameIsSlice && strings.HasPrefix(key, name) {
|
||||
suffix = key[len(name)+1:len(key)-1] // files[0][LocalFileId] 去掉 => LocalFileId
|
||||
} else if !strings.HasPrefix(key, name + ".") {
|
||||
suffix = key[len(name)+1 : len(key)-1] // files[0][LocalFileId] 去掉 => LocalFileId
|
||||
} else if !strings.HasPrefix(key, name+".") {
|
||||
noPrefix = true
|
||||
suffix = key
|
||||
// continue
|
||||
// continue
|
||||
} else {
|
||||
// Get the name of the struct property.
|
||||
// Strip off the prefix. e.g. foo.bar.baz => bar.baz
|
||||
suffix = key[len(name)+1:]
|
||||
}
|
||||
// fmt.Println(suffix);
|
||||
|
||||
// fmt.Println(suffix);
|
||||
|
||||
fieldName := nextKey(suffix) // e.g. bar => "bar", bar.baz => "bar", bar[0] => "bar"
|
||||
// fmt.Println(fieldName);
|
||||
// fmt.Println(fieldName);
|
||||
fieldLen := len(fieldName)
|
||||
|
||||
|
||||
if _, ok := fieldValues[fieldName]; !ok {
|
||||
// Time to bind this field. Get it and make sure we can set it.
|
||||
fieldName = strings.Title(fieldName) // 传过来title, 但struct是Title
|
||||
// fmt.Println("xx: " + fieldName)
|
||||
// fmt.Println("xx: " + fieldName)
|
||||
fieldValue := result.FieldByName(fieldName)
|
||||
// fmt.Println(fieldValue)
|
||||
// fmt.Println(fieldValue)
|
||||
if !fieldValue.IsValid() {
|
||||
continue
|
||||
}
|
||||
@@ -111,14 +112,14 @@ files[0][HasBody]:[true]]
|
||||
}
|
||||
var boundVal reflect.Value
|
||||
// 没有name前缀
|
||||
if(noPrefix) {
|
||||
if noPrefix {
|
||||
// life
|
||||
// fmt.Println("<<")
|
||||
// fmt.Println(strings.Title(key[:fieldLen]));
|
||||
// fmt.Println("<<")
|
||||
// fmt.Println(strings.Title(key[:fieldLen]));
|
||||
boundVal = revel.Bind(params, key[:fieldLen], fieldValue.Type())
|
||||
} else {
|
||||
// fmt.Println("final")
|
||||
// fmt.Println(key[:len(name)+1+fieldLen]) // files[0][HasBody
|
||||
// fmt.Println("final")
|
||||
// fmt.Println(key[:len(name)+1+fieldLen]) // files[0][HasBody
|
||||
if nameIsSlice {
|
||||
fieldLen += 1
|
||||
}
|
||||
@@ -153,4 +154,4 @@ func init() {
|
||||
revel.TypeBinders[reflect.TypeOf(controllers.NoteOrContent{})] = leanoteStructBinder
|
||||
revel.TypeBinders[reflect.TypeOf(info.ApiNote{})] = leanoteStructBinder
|
||||
revel.TypeBinders[reflect.TypeOf(info.NoteFile{})] = leanoteStructBinder
|
||||
}
|
||||
}
|
||||
+14
-16
@@ -6,8 +6,8 @@ import (
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
// "os"
|
||||
"fmt"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"regexp"
|
||||
@@ -40,8 +40,8 @@ type RenderTemplateResult struct {
|
||||
Template *template.Template
|
||||
PathContent map[string]string
|
||||
RenderArgs map[string]interface{}
|
||||
|
||||
IsPreview bool // 是否是预览
|
||||
|
||||
IsPreview bool // 是否是预览
|
||||
CurBlogTpl *BlogTpl
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func (r *RenderTemplateResult) render(req *revel.Request, resp *revel.Response,
|
||||
Line: line,
|
||||
SourceLines: templateContent,
|
||||
}
|
||||
|
||||
|
||||
// 这里, 错误!!
|
||||
// 这里应该导向到本主题的错误页面
|
||||
resp.Status = 500
|
||||
@@ -117,7 +117,7 @@ func (r *RenderTemplateResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
r.render(req, resp, out) // 这里!!!
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Render the template into a temporary buffer, to see if there was an error
|
||||
// rendering the template. If not, then copy it into the response buffer.
|
||||
// Otherwise, template render errors may result in unpredictable HTML (and
|
||||
@@ -139,7 +139,7 @@ func Init() {
|
||||
fileBytes, _ := ioutil.ReadFile(revel.ViewsPath + "/Blog/" + path)
|
||||
fileStr := string(fileBytes)
|
||||
path := "blog/" + path
|
||||
// path := path
|
||||
// path := path
|
||||
BlogTplObject.PathContent[path] = fileStr
|
||||
BlogTplObject.Template.New(path).Parse(fileStr) // 以blog为根
|
||||
}
|
||||
@@ -157,7 +157,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
// 都不会为空的
|
||||
if basePath == "" {
|
||||
path := "blog/" + name
|
||||
// path := name
|
||||
// path := name
|
||||
t := BlogTplObject.Template.Lookup(path)
|
||||
r = &RenderTemplateResult{
|
||||
Template: t,
|
||||
@@ -181,7 +181,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
files := ListDir(basePath)
|
||||
for _, t := range files {
|
||||
if !strings.Contains(t, ".html") {
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
fileBytes, err := ioutil.ReadFile(basePath + "/" + t)
|
||||
if err != nil {
|
||||
@@ -194,7 +194,7 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
|
||||
// 如果本主题下没有, 则用系统的
|
||||
t := newBlogTplObject.Template.Lookup(name)
|
||||
|
||||
|
||||
if t == nil {
|
||||
path := "blog/" + name
|
||||
t = BlogTplObject.Template.Lookup(path)
|
||||
@@ -203,23 +203,21 @@ func RenderTemplate(name string, args map[string]interface{}, basePath string, i
|
||||
Template: t,
|
||||
PathContent: newBlogTplObject.PathContent, // 为了显示错误
|
||||
RenderArgs: args,
|
||||
CurBlogTpl: newBlogTplObject,
|
||||
IsPreview: isPreview,
|
||||
CurBlogTpl: newBlogTplObject,
|
||||
IsPreview: isPreview,
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
//
|
||||
|
||||
|
||||
type ErrorResult struct {
|
||||
RenderArgs map[string]interface{}
|
||||
Error error
|
||||
IsPreview bool
|
||||
IsPreview bool
|
||||
CurBlogTpl *BlogTpl
|
||||
}
|
||||
|
||||
@@ -240,7 +238,7 @@ func (r ErrorResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
var err error
|
||||
templatePath := fmt.Sprintf("errors/%d.%s", status, format)
|
||||
err = nil
|
||||
// tmpl, err := revel.MainTemplateLoader.Template("index.html") // 这里找到错误页面主题
|
||||
// tmpl, err := revel.MainTemplateLoader.Template("index.html") // 这里找到错误页面主题
|
||||
|
||||
// This func shows a plaintext error message, in case the template rendering
|
||||
// doesn't work.
|
||||
@@ -297,4 +295,4 @@ func (r ErrorResult) Apply(req *revel.Request, resp *revel.Response) {
|
||||
resp.WriteHeader(http.StatusOK, "text/html; charset=utf-8")
|
||||
b.WriteTo(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
+346
-344
@@ -1,399 +1,401 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math/rand"
|
||||
crand "crypto/rand"
|
||||
"time"
|
||||
"strconv"
|
||||
)
|
||||
const (
|
||||
stdWidth = 100
|
||||
stdHeight = 40
|
||||
maxSkew = 2
|
||||
crand "crypto/rand"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"io"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
fontWidth = 5
|
||||
fontHeight = 8
|
||||
blackChar = 1
|
||||
stdWidth = 100
|
||||
stdHeight = 40
|
||||
maxSkew = 2
|
||||
)
|
||||
|
||||
|
||||
const (
|
||||
fontWidth = 5
|
||||
fontHeight = 8
|
||||
blackChar = 1
|
||||
)
|
||||
|
||||
var font = [][]byte{
|
||||
{ // 0
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 1
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 2
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 1,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 3
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 1, 1, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 4
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
},
|
||||
{ // 5
|
||||
1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 6
|
||||
0, 0, 1, 1, 1,
|
||||
0, 1, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 7
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
},
|
||||
{ // 8
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 9
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 1, 0, 0, 1,
|
||||
0, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 0
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 1
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 2
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 1,
|
||||
0, 1, 1, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
},
|
||||
{ // 3
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 1, 1, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 4
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 0, 0, 1, 0,
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
},
|
||||
{ // 5
|
||||
1, 1, 1, 1, 1,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 6
|
||||
0, 0, 1, 1, 1,
|
||||
0, 1, 0, 0, 0,
|
||||
1, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 7
|
||||
1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 1, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
},
|
||||
{ // 8
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
0, 1, 1, 1, 0,
|
||||
},
|
||||
{ // 9
|
||||
0, 1, 1, 1, 0,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 0, 0, 0, 1,
|
||||
1, 1, 0, 0, 1,
|
||||
0, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 0,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
type Image struct {
|
||||
*image.NRGBA
|
||||
color *color.NRGBA
|
||||
width int //a digit width
|
||||
height int //a digit height
|
||||
dotsize int
|
||||
*image.NRGBA
|
||||
color *color.NRGBA
|
||||
width int //a digit width
|
||||
height int //a digit height
|
||||
dotsize int
|
||||
}
|
||||
func init(){
|
||||
rand.Seed(int64(time.Second))
|
||||
|
||||
func init() {
|
||||
rand.Seed(int64(time.Second))
|
||||
}
|
||||
|
||||
|
||||
func NewImage(digits []byte, width, height int) *Image {
|
||||
img := new(Image)
|
||||
r := image.Rect(img.width, img.height, stdWidth, stdHeight)
|
||||
img.NRGBA = image.NewNRGBA(r)
|
||||
|
||||
img.color = &color.NRGBA{
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
0xFF,
|
||||
}
|
||||
// Draw background (10 random circles of random brightness)
|
||||
img.calculateSizes(width, height, len(digits))
|
||||
img.fillWithCircles(10, img.dotsize)
|
||||
|
||||
maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize
|
||||
maxy := height - img.height - img.dotsize*2
|
||||
|
||||
x := rnd(img.dotsize*2, maxx)
|
||||
y := rnd(img.dotsize*2, maxy)
|
||||
|
||||
// Draw digits.
|
||||
for _, n := range digits {
|
||||
img.drawDigit(font[n], x, y)
|
||||
x += img.width + img.dotsize
|
||||
}
|
||||
|
||||
// Draw strike-through line.
|
||||
// 中间线不要
|
||||
//img.strikeThrough()
|
||||
|
||||
return img
|
||||
img := new(Image)
|
||||
r := image.Rect(img.width, img.height, stdWidth, stdHeight)
|
||||
img.NRGBA = image.NewNRGBA(r)
|
||||
|
||||
img.color = &color.NRGBA{
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
uint8(rand.Intn(129)),
|
||||
0xFF,
|
||||
}
|
||||
// Draw background (10 random circles of random brightness)
|
||||
img.calculateSizes(width, height, len(digits))
|
||||
img.fillWithCircles(10, img.dotsize)
|
||||
|
||||
maxx := width - (img.width+img.dotsize)*len(digits) - img.dotsize
|
||||
maxy := height - img.height - img.dotsize*2
|
||||
|
||||
x := rnd(img.dotsize*2, maxx)
|
||||
y := rnd(img.dotsize*2, maxy)
|
||||
|
||||
// Draw digits.
|
||||
for _, n := range digits {
|
||||
img.drawDigit(font[n], x, y)
|
||||
x += img.width + img.dotsize
|
||||
}
|
||||
|
||||
// Draw strike-through line.
|
||||
// 中间线不要
|
||||
//img.strikeThrough()
|
||||
|
||||
return img
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) WriteTo(w io.Writer) (int64, error) {
|
||||
return 0, png.Encode(w, img)
|
||||
return 0, png.Encode(w, img)
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) calculateSizes(width, height, ncount int) {
|
||||
|
||||
// Goal: fit all digits inside the image.
|
||||
var border int
|
||||
if width > height {
|
||||
border = height / 5
|
||||
} else {
|
||||
border = width / 5
|
||||
}
|
||||
// Convert everything to floats for calculations.
|
||||
w := float64(width - border*2) //268
|
||||
h := float64(height - border*2) //48
|
||||
// fw takes into account 1-dot spacing between digits.
|
||||
|
||||
fw := float64(fontWidth) + 1 //6
|
||||
|
||||
fh := float64(fontHeight) //8
|
||||
nc := float64(ncount) //7
|
||||
|
||||
// Calculate the width of a single digit taking into account only the
|
||||
// width of the image.
|
||||
nw := w / nc //38
|
||||
// Calculate the height of a digit from this width.
|
||||
nh := nw * fh / fw //51
|
||||
|
||||
// Digit too high?
|
||||
|
||||
if nh > h {
|
||||
// Fit digits based on height.
|
||||
nh = h //nh = 44
|
||||
nw = fw / fh * nh
|
||||
}
|
||||
// Calculate dot size.
|
||||
img.dotsize = int(nh / fh)
|
||||
// Save everything, making the actual width smaller by 1 dot to account
|
||||
// for spacing between digits.
|
||||
img.width = int(nw)
|
||||
img.height = int(nh) - img.dotsize
|
||||
|
||||
// Goal: fit all digits inside the image.
|
||||
var border int
|
||||
if width > height {
|
||||
border = height / 5
|
||||
} else {
|
||||
border = width / 5
|
||||
}
|
||||
// Convert everything to floats for calculations.
|
||||
w := float64(width - border*2) //268
|
||||
h := float64(height - border*2) //48
|
||||
// fw takes into account 1-dot spacing between digits.
|
||||
|
||||
fw := float64(fontWidth) + 1 //6
|
||||
|
||||
fh := float64(fontHeight) //8
|
||||
nc := float64(ncount) //7
|
||||
|
||||
// Calculate the width of a single digit taking into account only the
|
||||
// width of the image.
|
||||
nw := w / nc //38
|
||||
// Calculate the height of a digit from this width.
|
||||
nh := nw * fh / fw //51
|
||||
|
||||
// Digit too high?
|
||||
|
||||
if nh > h {
|
||||
// Fit digits based on height.
|
||||
nh = h //nh = 44
|
||||
nw = fw / fh * nh
|
||||
}
|
||||
// Calculate dot size.
|
||||
img.dotsize = int(nh / fh)
|
||||
// Save everything, making the actual width smaller by 1 dot to account
|
||||
// for spacing between digits.
|
||||
img.width = int(nw)
|
||||
img.height = int(nh) - img.dotsize
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) fillWithCircles(n, maxradius int) {
|
||||
color := img.color
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
for i := 0; i < n; i++ {
|
||||
setRandomBrightness(color, 255)
|
||||
r := rnd(1, maxradius)
|
||||
img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r)
|
||||
}
|
||||
color := img.color
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
for i := 0; i < n; i++ {
|
||||
setRandomBrightness(color, 255)
|
||||
r := rnd(1, maxradius)
|
||||
img.drawCircle(color, rnd(r, maxx-r), rnd(r, maxy-r), r)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) drawHorizLine(color color.Color, fromX, toX, y int) {
|
||||
for x := fromX; x <= toX; x++ {
|
||||
img.Set(x, y, color)
|
||||
}
|
||||
for x := fromX; x <= toX; x++ {
|
||||
img.Set(x, y, color)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) drawCircle(color color.Color, x, y, radius int) {
|
||||
f := 1 - radius
|
||||
dfx := 1
|
||||
dfy := -2 * radius
|
||||
xx := 0
|
||||
yy := radius
|
||||
|
||||
img.Set(x, y+radius, color)
|
||||
img.Set(x, y-radius, color)
|
||||
img.drawHorizLine(color, x-radius, x+radius, y)
|
||||
|
||||
for xx < yy {
|
||||
if f >= 0 {
|
||||
yy--
|
||||
dfy += 2
|
||||
f += dfy
|
||||
}
|
||||
xx++
|
||||
dfx += 2
|
||||
f += dfx
|
||||
img.drawHorizLine(color, x-xx, x+xx, y+yy)
|
||||
img.drawHorizLine(color, x-xx, x+xx, y-yy)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y+xx)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y-xx)
|
||||
}
|
||||
f := 1 - radius
|
||||
dfx := 1
|
||||
dfy := -2 * radius
|
||||
xx := 0
|
||||
yy := radius
|
||||
|
||||
img.Set(x, y+radius, color)
|
||||
img.Set(x, y-radius, color)
|
||||
img.drawHorizLine(color, x-radius, x+radius, y)
|
||||
|
||||
for xx < yy {
|
||||
if f >= 0 {
|
||||
yy--
|
||||
dfy += 2
|
||||
f += dfy
|
||||
}
|
||||
xx++
|
||||
dfx += 2
|
||||
f += dfx
|
||||
img.drawHorizLine(color, x-xx, x+xx, y+yy)
|
||||
img.drawHorizLine(color, x-xx, x+xx, y-yy)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y+xx)
|
||||
img.drawHorizLine(color, x-yy, x+yy, y-xx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) strikeThrough() {
|
||||
r := 0
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
y := rnd(maxy/3, maxy-maxy/3)
|
||||
for x := 0; x < maxx; x += r {
|
||||
r = rnd(1, img.dotsize/3)
|
||||
y += rnd(-img.dotsize/2, img.dotsize/2)
|
||||
if y <= 0 || y >= maxy {
|
||||
y = rnd(maxy/3, maxy-maxy/3)
|
||||
}
|
||||
img.drawCircle(img.color, x, y, r)
|
||||
}
|
||||
r := 0
|
||||
maxx := img.Bounds().Max.X
|
||||
maxy := img.Bounds().Max.Y
|
||||
y := rnd(maxy/3, maxy-maxy/3)
|
||||
for x := 0; x < maxx; x += r {
|
||||
r = rnd(1, img.dotsize/3)
|
||||
y += rnd(-img.dotsize/2, img.dotsize/2)
|
||||
if y <= 0 || y >= maxy {
|
||||
y = rnd(maxy/3, maxy-maxy/3)
|
||||
}
|
||||
img.drawCircle(img.color, x, y, r)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (img *Image) drawDigit(digit []byte, x, y int) {
|
||||
skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew))
|
||||
xs := float64(x)
|
||||
minr := img.dotsize / 2 // minumum radius
|
||||
maxr := img.dotsize/2 + img.dotsize/4 // maximum radius
|
||||
y += rnd(-minr, minr)
|
||||
for yy := 0; yy < fontHeight; yy++ {
|
||||
for xx := 0; xx < fontWidth; xx++ {
|
||||
if digit[yy*fontWidth+xx] != blackChar {
|
||||
continue
|
||||
}
|
||||
// Introduce random variations.
|
||||
or := rnd(minr, maxr)
|
||||
ox := x + (xx * img.dotsize) + rnd(0, or/2)
|
||||
oy := y + (yy * img.dotsize) + rnd(0, or/2)
|
||||
|
||||
img.drawCircle(img.color, ox, oy, or)
|
||||
}
|
||||
xs += skf
|
||||
x = int(xs)
|
||||
}
|
||||
skf := rand.Float64() * float64(rnd(-maxSkew, maxSkew))
|
||||
xs := float64(x)
|
||||
minr := img.dotsize / 2 // minumum radius
|
||||
maxr := img.dotsize/2 + img.dotsize/4 // maximum radius
|
||||
y += rnd(-minr, minr)
|
||||
for yy := 0; yy < fontHeight; yy++ {
|
||||
for xx := 0; xx < fontWidth; xx++ {
|
||||
if digit[yy*fontWidth+xx] != blackChar {
|
||||
continue
|
||||
}
|
||||
// Introduce random variations.
|
||||
or := rnd(minr, maxr)
|
||||
ox := x + (xx * img.dotsize) + rnd(0, or/2)
|
||||
oy := y + (yy * img.dotsize) + rnd(0, or/2)
|
||||
|
||||
img.drawCircle(img.color, ox, oy, or)
|
||||
}
|
||||
xs += skf
|
||||
x = int(xs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func setRandomBrightness(c *color.NRGBA, max uint8) {
|
||||
minc := min3(c.R, c.G, c.B)
|
||||
maxc := max3(c.R, c.G, c.B)
|
||||
if maxc > max {
|
||||
return
|
||||
}
|
||||
n := rand.Intn(int(max-maxc)) - int(minc)
|
||||
c.R = uint8(int(c.R) + n)
|
||||
c.G = uint8(int(c.G) + n)
|
||||
c.B = uint8(int(c.B) + n)
|
||||
minc := min3(c.R, c.G, c.B)
|
||||
maxc := max3(c.R, c.G, c.B)
|
||||
if maxc > max {
|
||||
return
|
||||
}
|
||||
n := rand.Intn(int(max-maxc)) - int(minc)
|
||||
c.R = uint8(int(c.R) + n)
|
||||
c.G = uint8(int(c.G) + n)
|
||||
c.B = uint8(int(c.B) + n)
|
||||
}
|
||||
|
||||
|
||||
func min3(x, y, z uint8) (o uint8) {
|
||||
o = x
|
||||
if y < o {
|
||||
o = y
|
||||
}
|
||||
if z < o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
o = x
|
||||
if y < o {
|
||||
o = y
|
||||
}
|
||||
if z < o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
func max3(x, y, z uint8) (o uint8) {
|
||||
o = x
|
||||
if y > o {
|
||||
o = y
|
||||
}
|
||||
if z > o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
o = x
|
||||
if y > o {
|
||||
o = y
|
||||
}
|
||||
if z > o {
|
||||
o = z
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// rnd returns a random number in range [from, to].
|
||||
func rnd(from, to int) int {
|
||||
//println(to+1-from)
|
||||
return rand.Intn(to+1-from) + from
|
||||
//println(to+1-from)
|
||||
return rand.Intn(to+1-from) + from
|
||||
}
|
||||
|
||||
|
||||
const (
|
||||
// Standard length of uniuri string to achive ~95 bits of entropy.
|
||||
StdLen = 16
|
||||
// Length of uniurl string to achive ~119 bits of entropy, closest
|
||||
// to what can be losslessly converted to UUIDv4 (122 bits).
|
||||
UUIDLen = 20
|
||||
// Standard length of uniuri string to achive ~95 bits of entropy.
|
||||
StdLen = 16
|
||||
// Length of uniurl string to achive ~119 bits of entropy, closest
|
||||
// to what can be losslessly converted to UUIDv4 (122 bits).
|
||||
UUIDLen = 20
|
||||
)
|
||||
|
||||
|
||||
// Standard characters allowed in uniuri string.
|
||||
var StdChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
|
||||
|
||||
|
||||
// New returns a new random string of the standard length, consisting of
|
||||
// standard characters.
|
||||
func New() string {
|
||||
return NewLenChars(StdLen, StdChars)
|
||||
return NewLenChars(StdLen, StdChars)
|
||||
}
|
||||
|
||||
|
||||
// NewLen returns a new random string of the provided length, consisting of
|
||||
// standard characters.
|
||||
func NewLen(length int) string {
|
||||
return NewLenChars(length, StdChars)
|
||||
return NewLenChars(length, StdChars)
|
||||
}
|
||||
|
||||
|
||||
// NewLenChars returns a new random string of the provided length, consisting
|
||||
// of the provided byte slice of allowed characters (maximum 256).
|
||||
func NewLenChars(length int, chars []byte) string {
|
||||
b := make([]byte, length)
|
||||
r := make([]byte, length+(length/4)) // storage for random bytes.
|
||||
clen := byte(len(chars))
|
||||
maxrb := byte(256 - (256 % len(chars)))
|
||||
i := 0
|
||||
for {
|
||||
if _, err := io.ReadFull(crand.Reader, r); err != nil {
|
||||
panic("error reading from random source: " + err.Error())
|
||||
}
|
||||
for _, c := range r {
|
||||
if c >= maxrb {
|
||||
// Skip this number to avoid modulo bias.
|
||||
continue
|
||||
}
|
||||
b[i] = chars[c%clen]
|
||||
i++
|
||||
if i == length {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
b := make([]byte, length)
|
||||
r := make([]byte, length+(length/4)) // storage for random bytes.
|
||||
clen := byte(len(chars))
|
||||
maxrb := byte(256 - (256 % len(chars)))
|
||||
i := 0
|
||||
for {
|
||||
if _, err := io.ReadFull(crand.Reader, r); err != nil {
|
||||
panic("error reading from random source: " + err.Error())
|
||||
}
|
||||
for _, c := range r {
|
||||
if c >= maxrb {
|
||||
// Skip this number to avoid modulo bias.
|
||||
continue
|
||||
}
|
||||
b[i] = chars[c%clen]
|
||||
i++
|
||||
if i == length {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func Fetch() (*Image, string) {
|
||||
d := make([]byte, 4)
|
||||
s := NewLen(4)
|
||||
ss := ""
|
||||
d = []byte(s)
|
||||
for v := range d {
|
||||
d[v] %= 10
|
||||
ss += strconv.FormatInt(int64(d[v]), 32)
|
||||
}
|
||||
return NewImage(d, 100, 40), ss
|
||||
}
|
||||
d := make([]byte, 4)
|
||||
s := NewLen(4)
|
||||
ss := ""
|
||||
d = []byte(s)
|
||||
for v := range d {
|
||||
d[v] %= 10
|
||||
ss += strconv.FormatInt(int64(d[v]), 32)
|
||||
}
|
||||
return NewImage(d, 100, 40), ss
|
||||
}
|
||||
@@ -24,29 +24,29 @@ import (
|
||||
type Html2Image struct {
|
||||
image *image.RGBA
|
||||
gc *draw2d.ImageGraphicContext
|
||||
|
||||
|
||||
// 试探
|
||||
gc2 *draw2d.ImageGraphicContext
|
||||
|
||||
|
||||
width float64 // 图片宽度
|
||||
height float64
|
||||
|
||||
|
||||
painWidth float64 // 画布宽度
|
||||
|
||||
|
||||
startX float64
|
||||
x float64
|
||||
y float64
|
||||
|
||||
|
||||
isFirstP bool // 是否是第一个段落?
|
||||
|
||||
|
||||
// 换行和段落的高度
|
||||
brY float64
|
||||
pY float64
|
||||
|
||||
|
||||
// 字体
|
||||
normalFontFamily draw2d.FontData
|
||||
boldFontFamily draw2d.FontData
|
||||
|
||||
|
||||
// preTag 之前的标签
|
||||
preTag *html.Node
|
||||
}
|
||||
@@ -58,23 +58,23 @@ func NewHtml2Image() *Html2Image {
|
||||
i, gc := h.InitGc(h.width, h.height)
|
||||
h.gc = gc;
|
||||
h.image = i
|
||||
|
||||
|
||||
// 试探
|
||||
_, h.gc2 = h.InitGc(h.width, 100)
|
||||
|
||||
h.startX = 10
|
||||
|
||||
|
||||
h.startX = 10
|
||||
|
||||
// 最初位置
|
||||
h.x = h.startX
|
||||
h.y = 80
|
||||
|
||||
|
||||
h.isFirstP = true
|
||||
|
||||
|
||||
h.normalFontFamily = draw2d.FontData{"xihei", 4, draw2d.FontStyleNormal};
|
||||
h.boldFontFamily = draw2d.FontData{"heiti", 5, draw2d.FontStyleNormal};
|
||||
|
||||
|
||||
h.SetNormalFont()
|
||||
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
@@ -86,12 +86,12 @@ func (this *Html2Image) InitGc(w, h float64) (* image.RGBA, *draw2d.ImageGraphic
|
||||
gc.SetFillColor(image.White)
|
||||
// fill the background
|
||||
// gc.Clear()
|
||||
|
||||
|
||||
draw2d.SetFontFolder(revel.BasePath + "/public/fonts/weibo")
|
||||
draw2d.Rect(gc, 0, 0, w, h) // 设置背景
|
||||
gc.FillStroke()
|
||||
gc.SetFillColor(image.Black)
|
||||
|
||||
|
||||
// 这个很耗时
|
||||
// gc.Translate(0, 0)
|
||||
return i, gc
|
||||
@@ -101,7 +101,7 @@ func (this *Html2Image) SaveToPngFile(filePath string) bool {
|
||||
// m := this.image;
|
||||
m := this.image.SubImage(image.Rect(0, 0, int(this.width), int(this.y + 20)))
|
||||
// 需要截断之
|
||||
|
||||
|
||||
f, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return false
|
||||
@@ -124,14 +124,14 @@ func (this *Html2Image) SaveToPngFile(filePath string) bool {
|
||||
func (this *Html2Image) SetSmallFont() {
|
||||
this.gc.SetFontData(this.normalFontFamily)
|
||||
this.gc2.SetFontData(this.normalFontFamily)
|
||||
|
||||
|
||||
this.gc.SetFillColor(color.NRGBA{60, 60, 60, 255})
|
||||
this.gc.SetFontSize(12)
|
||||
this.gc2.SetFontSize(12)
|
||||
|
||||
|
||||
this.brY = 16
|
||||
this.pY = 30
|
||||
|
||||
|
||||
this.painWidth = this.width - 10
|
||||
}
|
||||
|
||||
@@ -139,13 +139,13 @@ func (this *Html2Image) SetNormalFont() {
|
||||
this.gc.SetFillColor(image.Black)
|
||||
this.gc.SetFontData(this.normalFontFamily)
|
||||
this.gc2.SetFontData(this.normalFontFamily)
|
||||
|
||||
|
||||
this.gc.SetFontSize(14)
|
||||
this.gc2.SetFontSize(14)
|
||||
|
||||
|
||||
this.brY = 20
|
||||
this.pY = 30
|
||||
|
||||
|
||||
this.painWidth = this.width - 10
|
||||
}
|
||||
func (this *Html2Image) SetAColor() {
|
||||
@@ -155,16 +155,16 @@ func (this *Html2Image) SetAColor() {
|
||||
// 标题
|
||||
func (this *Html2Image) SetTitleFont() {
|
||||
this.gc.SetFillColor(image.Black)
|
||||
|
||||
|
||||
this.gc.SetFontData(this.boldFontFamily)
|
||||
this.gc2.SetFontData(this.boldFontFamily)
|
||||
|
||||
|
||||
this.gc.SetFontSize(24)
|
||||
this.gc2.SetFontSize(24)
|
||||
|
||||
|
||||
this.brY = 30
|
||||
this.pY = 60
|
||||
|
||||
|
||||
this.painWidth = this.width - 100
|
||||
}
|
||||
|
||||
@@ -175,9 +175,9 @@ func (this *Html2Image) SetHeadFont(h string) {
|
||||
|
||||
this.gc.SetFontData(this.boldFontFamily)
|
||||
this.gc2.SetFontData(this.boldFontFamily)
|
||||
|
||||
|
||||
this.painWidth = this.width - 50
|
||||
|
||||
|
||||
if h == "h1" {
|
||||
this.gc.SetFontSize(20)
|
||||
this.gc2.SetFontSize(20)
|
||||
@@ -229,7 +229,7 @@ func (this *Html2Image) IsOver(r []rune) bool {
|
||||
// 以下的方法可以极大节约时间
|
||||
// a, b, c, d := this.gc2.GetStringBounds(string(r))
|
||||
// width2 := c - a + 2
|
||||
|
||||
|
||||
// fmt.Println(width2)
|
||||
// fmt.Println(c - a)
|
||||
|
||||
@@ -268,7 +268,7 @@ func (this *Html2Image) InsertText(text string, needTest bool, prefix string) {
|
||||
this.InsertText(text, true, prefix)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
r := []rune(text)
|
||||
// 试探吧, 可能需要截取
|
||||
if !needTest || !this.IsOver(r) {
|
||||
@@ -316,17 +316,17 @@ func (this *Html2Image) InsertText(text string, needTest bool, prefix string) {
|
||||
end = i
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 这一段写上
|
||||
// println("------>" + string(r[0:end]))
|
||||
|
||||
|
||||
// 这里, 判断后面一个是否是标点符号
|
||||
end = this.includePunctuation(r, end)
|
||||
this.InsertText(string(r[0:end]), false, prefix)
|
||||
this.NewBr()
|
||||
// 之后的
|
||||
this.InsertText(string(r[end:]), true, prefix)
|
||||
|
||||
|
||||
return;
|
||||
} else {
|
||||
// 没超出, 不用计算, 但出要看是否是结尾了
|
||||
@@ -351,17 +351,17 @@ func (this *Html2Image) InsertText(text string, needTest bool, prefix string) {
|
||||
end = maxRI + 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 这一段写上
|
||||
// println("-e----->" + string(r[0:end]))
|
||||
|
||||
|
||||
// 这里, 判断后面一个是否是标点符号
|
||||
end = this.includePunctuation(r, end)
|
||||
this.InsertText(string(r[0:end]), false, prefix)
|
||||
this.NewBr()
|
||||
// 之后的
|
||||
this.InsertText(string(r[end:]), true, prefix)
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -376,9 +376,9 @@ func (this *Html2Image) SetBottom(username, url string) {
|
||||
this.gc.SetStrokeColor(color.NRGBA{200, 0, 0, 255})
|
||||
this.gc.SetLineWidth(2)
|
||||
this.gc.FillStroke()
|
||||
|
||||
|
||||
this.SetSmallFont()
|
||||
|
||||
|
||||
// 左侧写字
|
||||
this.NewP()
|
||||
this.InsertText("本文来自 " + username + " 的leanote笔记", true, " ")
|
||||
@@ -389,11 +389,11 @@ func (this *Html2Image) SetBottom(username, url string) {
|
||||
siteUrl = "http://leanote.com"
|
||||
}
|
||||
this.InsertA(siteUrl + "/blog/" + username, false)
|
||||
|
||||
|
||||
this.setLogo()
|
||||
// this.painWidth = this.width - 100
|
||||
// this.NewP()
|
||||
// this.InsertText("leanote, 不一样的笔记.", false, " ")
|
||||
// this.InsertText("leanote, 不一样的笔记.", false, " ")
|
||||
// this.NewBr()
|
||||
// this.InsertText("在这里你可以管理自己的知识", false, " ")
|
||||
// this.NewBr()
|
||||
@@ -401,7 +401,7 @@ func (this *Html2Image) SetBottom(username, url string) {
|
||||
// this.NewBr()
|
||||
// this.InsertText("并且还可以将笔记设为博客公开", false, " ")
|
||||
// this.InsertText(". 赶紧加入吧! leanote.com", false, "")
|
||||
//
|
||||
//
|
||||
// Logo
|
||||
}
|
||||
|
||||
@@ -411,7 +411,7 @@ func (this *Html2Image) setImage(path string, x, y float64) {
|
||||
return;
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
var m1 image.Image
|
||||
_, ext := lea.SplitFilename(path)
|
||||
if ext == ".png" {
|
||||
@@ -424,8 +424,8 @@ func (this *Html2Image) setImage(path string, x, y float64) {
|
||||
if err != nil {
|
||||
return
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.gc.Translate(x, y)
|
||||
this.gc.DrawImage(m1)
|
||||
this.gc.Translate(-x, -y)
|
||||
@@ -448,10 +448,10 @@ func (this *Html2Image) InsertA(text string, isNormal bool) {
|
||||
if text == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
this.SetAColor()
|
||||
this.InsertText(text, true, "")
|
||||
|
||||
|
||||
// 还原
|
||||
if isNormal {
|
||||
this.SetNormalFont()
|
||||
@@ -464,17 +464,17 @@ func (this *Html2Image) InsertA(text string, isNormal bool) {
|
||||
func (this *Html2Image) InsertTitle(title string) {
|
||||
oldX := this.x
|
||||
oldY := this.y - 35
|
||||
|
||||
|
||||
// 插入之
|
||||
this.SetTitleFont()
|
||||
|
||||
|
||||
this.InsertText(title, true, " ")
|
||||
|
||||
|
||||
// 还原字体大小
|
||||
this.SetNormalFont()
|
||||
|
||||
|
||||
this.NewBr()
|
||||
|
||||
|
||||
this.gc.MoveTo(oldX, oldY)
|
||||
this.gc.LineTo(this.x, this.y - 10)
|
||||
this.gc.SetStrokeColor(color.NRGBA{200, 0, 0, 255})
|
||||
@@ -512,7 +512,7 @@ func (this *Html2Image) InsertCode(n *html.Node) {
|
||||
}
|
||||
}
|
||||
this.NewBr()
|
||||
|
||||
|
||||
this.gc.MoveTo(oldX, oldY)
|
||||
this.gc.LineTo(this.x, this.y - 20)
|
||||
this.gc.SetStrokeColor(color.NRGBA{0, 200, 0, 255})
|
||||
@@ -521,14 +521,14 @@ func (this *Html2Image) InsertCode(n *html.Node) {
|
||||
}
|
||||
|
||||
// 插入图片
|
||||
// 这个path应该是url,
|
||||
// 这个path应该是url,
|
||||
// http://abc.com/a.gif 需要先下载
|
||||
// 或 /upload/a.gif
|
||||
func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
if path == "" {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 是url, 那么取网络图片之
|
||||
var ok bool
|
||||
if strings.HasPrefix(path, "http") || strings.HasPrefix(path, "//") {
|
||||
@@ -539,7 +539,7 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
} else {
|
||||
path = revel.BasePath + "/public/" + path
|
||||
}
|
||||
|
||||
|
||||
// 需要转换, logo不需要转换
|
||||
if(needTrans) {
|
||||
painWidth := uint(this.painWidth - 10)
|
||||
@@ -557,7 +557,7 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
return;
|
||||
panic(err)
|
||||
}
|
||||
|
||||
|
||||
var m1 image.Image
|
||||
_, ext := lea.SplitFilename(path)
|
||||
if ext == ".png" {
|
||||
@@ -568,8 +568,8 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
if err != nil {
|
||||
return
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 如果之前是p, 那么不要有<br>
|
||||
if this.preTag.Data != "p" {
|
||||
this.NewBr()
|
||||
@@ -580,9 +580,9 @@ func (this *Html2Image) InsertImage(path string, needTrans bool, width uint) {
|
||||
this.gc.Translate(-this.x, -this.y) // 这个有用些
|
||||
this.y += float64(m1.Bounds().Dy()) - 20
|
||||
this.NewP()
|
||||
|
||||
|
||||
os.Remove(path)
|
||||
|
||||
|
||||
// 如果图片是文章第一个的话, 之后的需要p
|
||||
this.isFirstP = false
|
||||
}
|
||||
@@ -605,7 +605,7 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
this.preTag = n
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
// 标签
|
||||
if n.Type == html.ElementNode {
|
||||
if n.Data == "p" {
|
||||
@@ -616,7 +616,7 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 也是一个段落, 只是要缩进
|
||||
if n.Data == "ul" || n.Data == "ol" {
|
||||
this.NewP()
|
||||
@@ -637,7 +637,7 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
} else {
|
||||
f(c, n, "")
|
||||
}
|
||||
|
||||
|
||||
if c.Type == html.ElementNode {
|
||||
if c.Data == "br" || c.Data == "p" {
|
||||
needPrefix = true
|
||||
@@ -650,19 +650,19 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
this.NewBr()
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 标题
|
||||
if n.Data == "h1" || n.Data == "h2" || n.Data == "h3" || n.Data == "h4" {
|
||||
this.InsertHead(n)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if n.Data == "pre" {
|
||||
// 把之后的全拿过来
|
||||
this.InsertCode(n)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 图片
|
||||
// 得到src
|
||||
if n.Data == "img" {
|
||||
@@ -680,22 +680,22 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 链接
|
||||
// 如果链接里只有文本, 那么单独处理, 如果还有其它的, 不作链接处理
|
||||
if n.Data == "a" {
|
||||
if n.FirstChild == n.LastChild {
|
||||
this.InsertA(n.FirstChild.Data, true)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 空行
|
||||
if n.Data == "br" { // || n.Data == "div"
|
||||
this.NewBr()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 是文本, 输出之
|
||||
if n.Type == html.TextNode {
|
||||
data := strings.TrimSpace(n.Data);
|
||||
@@ -705,36 +705,36 @@ func (this *Html2Image) InsertBody(htmlStr string) (ok bool) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// 其余的
|
||||
|
||||
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
f(c, n, prefix)
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
f(doc, nil, "")
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 主函数
|
||||
func ToImage(uid, username, noteId, title, htmlStr, toPath string) (ok bool) {
|
||||
h := NewHtml2Image()
|
||||
|
||||
|
||||
// 标题
|
||||
h.InsertTitle(title)
|
||||
|
||||
|
||||
// 主体
|
||||
ok = h.InsertBody(htmlStr)
|
||||
if(!ok) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 页眉与页脚
|
||||
h.SetBottom(username, "")
|
||||
|
||||
|
||||
// 保存成png图片
|
||||
ok = h.SaveToPngFile(toPath)
|
||||
return
|
||||
@@ -757,4 +757,4 @@ func TestFillString() {
|
||||
|
||||
func ToImage(uid, username, noteId, title, htmlStr, toPath string) (ok bool) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -7,4 +7,3 @@ import (
|
||||
func Html2Image(userInfo info.User, note info.Note, content, toPath string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
+38
-37
@@ -1,12 +1,13 @@
|
||||
package netutil
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"os"
|
||||
// "path/filepath"
|
||||
"strings"
|
||||
// "path/filepath"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
. "github.com/leanote/leanote/app/lea"
|
||||
)
|
||||
|
||||
// net的util
|
||||
@@ -16,33 +17,33 @@ import (
|
||||
// 返回文件的完整目录
|
||||
func WriteUrl(url string, toPath string) (length int64, newFilename, path string, ok bool) {
|
||||
if url == "" {
|
||||
return;
|
||||
return
|
||||
}
|
||||
content, err := GetContent(url)
|
||||
if err != nil {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
length = int64(len(content))
|
||||
|
||||
|
||||
// a.html?a=a11&xxx
|
||||
url = trimQueryParams(url)
|
||||
_, ext := SplitFilename(url)
|
||||
if toPath == "" {
|
||||
toPath = "/tmp"
|
||||
}
|
||||
// dir := filepath.Dir(toPath)
|
||||
// dir := filepath.Dir(toPath)
|
||||
newFilename = NewGuid() + ext
|
||||
fullPath := toPath + "/" + newFilename
|
||||
|
||||
|
||||
// 写到文件中
|
||||
file, err := os.Create(fullPath)
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return
|
||||
defer file.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
file.Write(content)
|
||||
|
||||
|
||||
path = fullPath
|
||||
ok = true
|
||||
return
|
||||
@@ -53,43 +54,43 @@ func GetContent(url string) (content []byte, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = http.Get(url)
|
||||
Log(err)
|
||||
if(resp != nil && resp.Body != nil) {
|
||||
if resp != nil && resp.Body != nil {
|
||||
defer resp.Body.Close()
|
||||
} else {
|
||||
}
|
||||
if resp == nil || resp.Body == nil || err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
buf, err = ioutil.ReadAll(resp.Body)
|
||||
if(err != nil) {
|
||||
Log(err)
|
||||
if resp == nil || resp.Body == nil || err != nil || resp.StatusCode != http.StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
content = buf;
|
||||
err = nil
|
||||
return
|
||||
|
||||
var buf []byte
|
||||
buf, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
Log(err)
|
||||
return
|
||||
}
|
||||
|
||||
content = buf
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
|
||||
// 将url ?, #后面的字符串去掉
|
||||
func trimQueryParams(url string) string {
|
||||
pos := strings.Index(url, "?");
|
||||
pos := strings.Index(url, "?")
|
||||
if pos != -1 {
|
||||
url = Substr(url, 0, pos);
|
||||
url = Substr(url, 0, pos)
|
||||
}
|
||||
|
||||
pos = strings.Index(url, "#");
|
||||
|
||||
pos = strings.Index(url, "#")
|
||||
if pos != -1 {
|
||||
url = Substr(url, 0, pos);
|
||||
url = Substr(url, 0, pos)
|
||||
}
|
||||
|
||||
pos = strings.Index(url, "!");
|
||||
|
||||
pos = strings.Index(url, "!")
|
||||
if pos != -1 {
|
||||
url = Substr(url, 0, pos);
|
||||
url = Substr(url, 0, pos)
|
||||
}
|
||||
return url;
|
||||
return url
|
||||
}
|
||||
|
||||
// 通过domain得到ip
|
||||
@@ -99,4 +100,4 @@ func GetIpFromDomain(domain string) string {
|
||||
return ip[0].String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
}
|
||||
+17
-17
@@ -1,9 +1,9 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"github.com/revel/revel"
|
||||
"github.com/leanote/leanote/app/db"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"github.com/revel/revel"
|
||||
// . "github.com/leanote/leanote/app/lea"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
@@ -11,10 +11,11 @@ import (
|
||||
// overwite revel RouterFilter
|
||||
// /api/user/Info => ApiUser.Info()
|
||||
var staticPrefix = []string{"/public", "/favicon.ico", "/css", "/js", "/images", "/tinymce", "/upload", "/fonts"}
|
||||
|
||||
func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
// 补全controller部分
|
||||
path := c.Request.Request.URL.Path
|
||||
|
||||
|
||||
// Figure out the Controller/Action
|
||||
var route *revel.RouteMatch = revel.MainRouter.Route(c.Request.Request)
|
||||
if route == nil {
|
||||
@@ -27,29 +28,29 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
c.Result = c.NotFound("(intentionally)")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
//----------
|
||||
// life start
|
||||
/*
|
||||
type URL struct {
|
||||
Scheme string
|
||||
Opaque string // encoded opaque data
|
||||
User *Userinfo // username and password information
|
||||
Host string // host or host:port
|
||||
Path string
|
||||
RawQuery string // encoded query values, without '?'
|
||||
Fragment string // fragment for references, without '#'
|
||||
}
|
||||
type URL struct {
|
||||
Scheme string
|
||||
Opaque string // encoded opaque data
|
||||
User *Userinfo // username and password information
|
||||
Host string // host or host:port
|
||||
Path string
|
||||
RawQuery string // encoded query values, without '?'
|
||||
Fragment string // fragment for references, without '#'
|
||||
}
|
||||
*/
|
||||
if route.ControllerName != "Static" {
|
||||
|
||||
// 检查mongodb 是否lost
|
||||
db.CheckMongoSessionLost()
|
||||
|
||||
|
||||
// api设置
|
||||
// leanote.com/api/user/get => ApiUser::Get
|
||||
//* /api/login ApiAuth.Login, 这里的设置, 其实已经转成了ApiAuth了
|
||||
if strings.HasPrefix(path, "/api") && !strings.HasPrefix(route.ControllerName, "Api"){
|
||||
if strings.HasPrefix(path, "/api") && !strings.HasPrefix(route.ControllerName, "Api") {
|
||||
route.ControllerName = "Api" + route.ControllerName
|
||||
} else if strings.HasPrefix(path, "/member") && !strings.HasPrefix(route.ControllerName, "Member") {
|
||||
// member设置
|
||||
@@ -57,7 +58,7 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
}
|
||||
// end
|
||||
}
|
||||
|
||||
|
||||
// Set the action.
|
||||
if err := c.SetAction(route.ControllerName, route.MethodName); err != nil {
|
||||
c.Result = c.NotFound(err.Error())
|
||||
@@ -84,4 +85,3 @@ func RouterFilter(c *revel.Controller, fc []revel.Filter) {
|
||||
|
||||
fc[0](c, fc[1:])
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user