Browse Source

Modules progress

Vova Tkach 6 years ago
parent
commit
7166faf3f7
5 changed files with 192 additions and 114 deletions
  1. 24 21
      engine/engine.go
  2. 59 11
      engine/wrapper/wrapper.go
  3. 14 26
      modules/module_index.go
  4. 66 56
      modules/modules.go
  5. 29 0
      utils/utils.go

+ 24 - 21
engine/engine.go

@@ -1,7 +1,7 @@
 package engine
 package engine
 
 
 import (
 import (
-	"database/sql"
+	//"database/sql"
 	"net/http"
 	"net/http"
 	"os"
 	"os"
 	"strings"
 	"strings"
@@ -35,6 +35,7 @@ func Response(l *logger.Logger, m *modules.Modules, w http.ResponseWriter, r *ht
 func (this *Engine) Process() bool {
 func (this *Engine) Process() bool {
 	this.Wrap.IsBackend = this.Wrap.R.URL.Path == "/cp" || strings.HasPrefix(this.Wrap.R.URL.Path, "/cp/")
 	this.Wrap.IsBackend = this.Wrap.R.URL.Path == "/cp" || strings.HasPrefix(this.Wrap.R.URL.Path, "/cp/")
 	this.Wrap.ConfMysqlExists = utils.IsMySqlConfigExists(this.Wrap.DConfig + string(os.PathSeparator) + "mysql.json")
 	this.Wrap.ConfMysqlExists = utils.IsMySqlConfigExists(this.Wrap.DConfig + string(os.PathSeparator) + "mysql.json")
+	this.Wrap.UrlArgs = append(this.Wrap.UrlArgs, utils.UrlToArray(this.Wrap.R.URL.Path)...)
 
 
 	// Action
 	// Action
 	if this.Mods.XXXActionFire(this.Wrap) {
 	if this.Mods.XXXActionFire(this.Wrap) {
@@ -54,28 +55,30 @@ func (this *Engine) Process() bool {
 		return true
 		return true
 	}
 	}
 
 
-	// Read MySQL settings file
-	mc, err := utils.MySqlConfigRead(this.Wrap.DConfig + string(os.PathSeparator) + "mysql.json")
-	if err != nil {
-		utils.SystemErrorPageEngine(this.Wrap.W, err)
-		return true
-	}
+	/*
+		// Read MySQL settings file
+		mc, err := utils.MySqlConfigRead(this.Wrap.DConfig + string(os.PathSeparator) + "mysql.json")
+		if err != nil {
+			utils.SystemErrorPageEngine(this.Wrap.W, err)
+			return true
+		}
 
 
-	// Connect to MySQL server
-	db, err := sql.Open("mysql", mc.User+":"+mc.Password+"@tcp("+mc.Host+":"+mc.Port+")/"+mc.Name)
-	if err != nil {
-		utils.SystemErrorPageEngine(this.Wrap.W, err)
-		return true
-	}
-	this.Wrap.DB = db
-	defer db.Close()
-	err = db.Ping()
+		// Connect to MySQL server
+		db, err := sql.Open("mysql", mc.User+":"+mc.Password+"@tcp("+mc.Host+":"+mc.Port+")/"+mc.Name)
+		if err != nil {
+			utils.SystemErrorPageEngine(this.Wrap.W, err)
+			return true
+		}
+		this.Wrap.DB = db
+		defer db.Close()
+		err = db.Ping()
 
 
-	// Check if MySQL server alive
-	if err != nil {
-		utils.SystemErrorPageEngine(this.Wrap.W, err)
-		return true
-	}
+		// Check if MySQL server alive
+		if err != nil {
+			utils.SystemErrorPageEngine(this.Wrap.W, err)
+			return true
+		}
+	*/
 
 
 	// Separated logic
 	// Separated logic
 	if this.Wrap.IsBackend {
 	if this.Wrap.IsBackend {

+ 59 - 11
engine/wrapper/wrapper.go

@@ -2,9 +2,14 @@ package wrapper
 
 
 import (
 import (
 	"database/sql"
 	"database/sql"
+	"errors"
+	"fmt"
 	"net/http"
 	"net/http"
+	"os"
+	"strings"
 
 
 	"golang-fave/logger"
 	"golang-fave/logger"
+	"golang-fave/utils"
 
 
 	_ "github.com/go-sql-driver/mysql"
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/vladimirok5959/golang-server-sessions/session"
 	"github.com/vladimirok5959/golang-server-sessions/session"
@@ -27,23 +32,27 @@ type Wrapper struct {
 
 
 	IsBackend       bool
 	IsBackend       bool
 	ConfMysqlExists bool
 	ConfMysqlExists bool
+	UrlArgs         []string
+	CurrModule      string
 
 
 	DB *sql.DB
 	DB *sql.DB
 }
 }
 
 
 func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string) *Wrapper {
 func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string) *Wrapper {
 	return &Wrapper{
 	return &Wrapper{
-		l:         l,
-		W:         w,
-		R:         r,
-		S:         s,
-		Host:      host,
-		Port:      port,
-		DConfig:   dirConfig,
-		DHtdocs:   dirHtdocs,
-		DLogs:     dirLogs,
-		DTemplate: dirTemplate,
-		DTmp:      dirTmp,
+		l:          l,
+		W:          w,
+		R:          r,
+		S:          s,
+		Host:       host,
+		Port:       port,
+		DConfig:    dirConfig,
+		DHtdocs:    dirHtdocs,
+		DLogs:      dirLogs,
+		DTemplate:  dirTemplate,
+		DTmp:       dirTmp,
+		UrlArgs:    []string{},
+		CurrModule: "index",
 	}
 	}
 }
 }
 
 
@@ -54,3 +63,42 @@ func (this *Wrapper) LogAccess(msg string) {
 func (this *Wrapper) LogError(msg string) {
 func (this *Wrapper) LogError(msg string) {
 	this.l.Log(msg, this.R, true)
 	this.l.Log(msg, this.R, true)
 }
 }
+
+func (this *Wrapper) UseDatabase() error {
+	if this.DB != nil {
+		return errors.New("already connected to database")
+	}
+	if !utils.IsMySqlConfigExists(this.DConfig + string(os.PathSeparator) + "mysql.json") {
+		return errors.New("can't read database configuration file")
+	}
+	mc, err := utils.MySqlConfigRead(this.DConfig + string(os.PathSeparator) + "mysql.json")
+	if err != nil {
+		return err
+	}
+	this.DB, err = sql.Open("mysql", mc.User+":"+mc.Password+"@tcp("+mc.Host+":"+mc.Port+")/"+mc.Name)
+	if err != nil {
+		return err
+	}
+	err = this.DB.Ping()
+	if err != nil {
+		this.DB.Close()
+		return err
+	}
+	return nil
+}
+
+func (this *Wrapper) Write(data string) {
+	this.W.Write([]byte(data))
+}
+
+func (this *Wrapper) MsgSuccess(msg string) {
+	this.Write(fmt.Sprintf(
+		`ShowSystemMsgSuccess('Success!', '%s', false);`,
+		strings.Replace(strings.Replace(msg, `'`, `’`, -1), `"`, `”`, -1)))
+}
+
+func (this *Wrapper) MsgError(msg string) {
+	this.Write(fmt.Sprintf(
+		`ShowSystemMsgError('Error!', '%s', true);`,
+		strings.Replace(strings.Replace(msg, `'`, `’`, -1), `"`, `”`, -1)))
+}

+ 14 - 26
modules/module_index.go

@@ -7,33 +7,21 @@ import (
 )
 )
 
 
 func (this *Modules) RegisterModule_index() *Module {
 func (this *Modules) RegisterModule_index() *Module {
-	return &Module{
-		Id:   "index",
-		Name: "Pages",
-		FrontEnd: func(mod *Modules, wrap *wrapper.Wrapper) {
-			fmt.Printf("FrontEnd func call\n")
-		},
-		BackEnd: func(mod *Modules, wrap *wrapper.Wrapper) {
-			fmt.Printf("BackEnd func call\n")
-		},
-	}
+	return this.newModule(false, "Pages", func(wrap *wrapper.Wrapper) {
+		fmt.Printf("FrontEnd func call\n")
+	}, func(wrap *wrapper.Wrapper) {
+		fmt.Printf("BackEnd func call\n")
+	})
 }
 }
 
 
-func (this *Modules) RegisterAction_test() *Action {
-	return &Action{
-		Id: "test",
-		ActFunc: func(mod *Modules, wrap *wrapper.Wrapper) {
-			fmt.Printf("ActFunc func call\n")
-		},
-	}
+func (this *Modules) RegisterAction_mysql() *Action {
+	return this.newAction(false, func(wrap *wrapper.Wrapper) {
+		fmt.Printf("ActFunc func call\n")
+	})
 }
 }
 
 
-/*
-func (this *Modules) module_index_frontend(wrap *wrapper.Wrapper) {
-	//
-}
-
-func (this *Modules) module_index_backend(wrap *wrapper.Wrapper) {
-	//
-}
-*/
+// All actions here...
+// MySQL install
+// MySQL first user
+// User login
+// User logout

+ 66 - 56
modules/modules.go

@@ -1,48 +1,33 @@
 package modules
 package modules
 
 
 import (
 import (
-	"fmt"
+	"net/http"
 	"reflect"
 	"reflect"
 	"strings"
 	"strings"
 
 
 	"golang-fave/engine/wrapper"
 	"golang-fave/engine/wrapper"
 )
 )
 
 
-type FuncFrontEnd func(mod *Modules, wrap *wrapper.Wrapper)
-type FuncBackEnd func(mod *Modules, wrap *wrapper.Wrapper)
-type FuncAction func(mod *Modules, wrap *wrapper.Wrapper)
-
 type Module struct {
 type Module struct {
 	Id       string
 	Id       string
+	WantDB   bool
 	Name     string
 	Name     string
-	FrontEnd FuncFrontEnd
-	BackEnd  FuncBackEnd
+	FrontEnd func(wrap *wrapper.Wrapper)
+	BackEnd  func(wrap *wrapper.Wrapper)
 }
 }
 
 
 type Action struct {
 type Action struct {
 	Id      string
 	Id      string
-	ActFunc FuncAction
+	WantDB  bool
+	ActFunc func(wrap *wrapper.Wrapper)
 }
 }
 
 
 type Modules struct {
 type Modules struct {
-	mods map[string]Module
-	acts map[string]Action
-}
-
-func New() *Modules {
-	m := Modules{
-		mods: map[string]Module{},
-		acts: map[string]Action{},
-	}
-	m.load()
-	return &m
+	mods map[string]*Module
+	acts map[string]*Action
 }
 }
 
 
 func (this *Modules) load() {
 func (this *Modules) load() {
-	// Called before server starts
-	fmt.Println("Load modules")
-	fmt.Println("---")
-
 	t := reflect.TypeOf(this)
 	t := reflect.TypeOf(this)
 	for i := 0; i < t.NumMethod(); i++ {
 	for i := 0; i < t.NumMethod(); i++ {
 		m := t.Method(i)
 		m := t.Method(i)
@@ -50,63 +35,88 @@ func (this *Modules) load() {
 			continue
 			continue
 		}
 		}
 		if strings.HasPrefix(m.Name, "RegisterModule_") {
 		if strings.HasPrefix(m.Name, "RegisterModule_") {
-			//fmt.Printf("%s\n", m.Name)
 			id := m.Name[15:]
 			id := m.Name[15:]
-			fmt.Printf("Module (%s)\n", id)
-
 			if _, ok := reflect.TypeOf(this).MethodByName("RegisterModule_" + id); ok {
 			if _, ok := reflect.TypeOf(this).MethodByName("RegisterModule_" + id); ok {
 				result := reflect.ValueOf(this).MethodByName("RegisterModule_" + id).Call([]reflect.Value{})
 				result := reflect.ValueOf(this).MethodByName("RegisterModule_" + id).Call([]reflect.Value{})
 				if len(result) >= 1 {
 				if len(result) >= 1 {
-					//fmt.Printf("--- result -> (%d)\n", len(result))
-					//fmt.Printf("%v\n", result[0])
-					//fmt.Printf("%T\n", result)
-					//mod := result[0]
-					//mod := result[0]
-					//fmt.Printf("%v\n", mod)
-					//fmt.Printf("%s\n", *Module(mod).Id)
 					mod := result[0].Interface().(*Module)
 					mod := result[0].Interface().(*Module)
-					fmt.Printf("%s\n", mod.Id)
+					mod.Id = id
+					this.mods[mod.Id] = mod
 				}
 				}
-			} else {
-				fmt.Printf("Error\n")
 			}
 			}
-			// Add to array
-			//mod := 
-			/*
-			if _, ok := reflect.TypeOf(this).MethodByName(mname); ok {
-				result := reflect.ValueOf(this).MethodByName(mname).Call([]reflect.Value{})
-				return result[0].String()
-			}
-			*/
 		}
 		}
 		if strings.HasPrefix(m.Name, "RegisterAction_") {
 		if strings.HasPrefix(m.Name, "RegisterAction_") {
-			//fmt.Printf("%s\n", m.Name)
 			id := m.Name[15:]
 			id := m.Name[15:]
-			fmt.Printf("Action (%s)\n", id)
-			// Add to array
+			if _, ok := reflect.TypeOf(this).MethodByName("RegisterAction_" + id); ok {
+				result := reflect.ValueOf(this).MethodByName("RegisterAction_" + id).Call([]reflect.Value{})
+				if len(result) >= 1 {
+					act := result[0].Interface().(*Action)
+					act.Id = id
+					this.acts[act.Id] = act
+				}
+			}
 		}
 		}
 	}
 	}
 }
 }
 
 
-// All actions here...
-// MySQL install
-// MySQL first user
-// User login
-// User logout
+func (this *Modules) newModule(WantDB bool, Name string, ff func(wrap *wrapper.Wrapper), bf func(wrap *wrapper.Wrapper)) *Module {
+	return &Module{
+		WantDB:   WantDB,
+		Name:     Name,
+		FrontEnd: ff,
+		BackEnd:  bf,
+	}
+}
+
+func (this *Modules) newAction(WantDB bool, af func(wrap *wrapper.Wrapper)) *Action {
+	return &Action{
+		WantDB:  WantDB,
+		ActFunc: af,
+	}
+}
+
+func New() *Modules {
+	m := Modules{
+		mods: map[string]*Module{},
+		acts: map[string]*Action{},
+	}
+	m.load()
+	return &m
+}
 
 
-// Called inside goroutine
 func (this *Modules) XXXActionFire(wrap *wrapper.Wrapper) bool {
 func (this *Modules) XXXActionFire(wrap *wrapper.Wrapper) bool {
-	//
+	if wrap.R.Method == "POST" {
+		if err := wrap.R.ParseForm(); err == nil {
+			name := wrap.R.FormValue("action")
+			if name != "" {
+				wrap.W.WriteHeader(http.StatusOK)
+				wrap.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+				wrap.W.Header().Set("Content-Type", "text/html; charset=utf-8")
+				if act, ok := this.acts[name]; ok {
+					if act.WantDB {
+						err := wrap.UseDatabase()
+						if err != nil {
+							wrap.MsgError(err.Error())
+							return true
+						}
+					}
+					act.ActFunc(wrap)
+					return true
+				} else {
+					wrap.MsgError(`This action is not implemented`)
+					return true
+				}
+			}
+		}
+	}
 	return false
 	return false
 }
 }
 
 
-// Called inside goroutine
 func (this *Modules) XXXFrontEnd(wrap *wrapper.Wrapper) bool {
 func (this *Modules) XXXFrontEnd(wrap *wrapper.Wrapper) bool {
 	//
 	//
 	return false
 	return false
 }
 }
 
 
-// Called inside goroutine
 func (this *Modules) XXXBackEnd(wrap *wrapper.Wrapper) bool {
 func (this *Modules) XXXBackEnd(wrap *wrapper.Wrapper) bool {
 	//
 	//
 	return false
 	return false

+ 29 - 0
utils/utils.go

@@ -1,9 +1,12 @@
 package utils
 package utils
 
 
 import (
 import (
+	"crypto/md5"
+	"encoding/hex"
 	"html/template"
 	"html/template"
 	"net/http"
 	"net/http"
 	"os"
 	"os"
+	"regexp"
 	"strings"
 	"strings"
 
 
 	"golang-fave/assets"
 	"golang-fave/assets"
@@ -37,6 +40,11 @@ func IsDirExists(path string) bool {
 	return false
 	return false
 }
 }
 
 
+func IsValidEmail(email string) bool {
+	regexpe := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
+	return regexpe.MatchString(email)
+}
+
 func FixPath(path string) string {
 func FixPath(path string) string {
 	newPath := strings.TrimSpace(path)
 	newPath := strings.TrimSpace(path)
 	if len(newPath) <= 0 {
 	if len(newPath) <= 0 {
@@ -86,6 +94,12 @@ func GetTmplError(err error) consts.TmplError {
 	}
 	}
 }
 }
 
 
+func GetMd5(str string) string {
+	hasher := md5.New()
+	hasher.Write([]byte(str))
+	return hex.EncodeToString(hasher.Sum(nil))
+}
+
 func SystemRenderTemplate(w http.ResponseWriter, c []byte, d interface{}) {
 func SystemRenderTemplate(w http.ResponseWriter, c []byte, d interface{}) {
 	tmpl, err := template.New("template").Parse(string(c))
 	tmpl, err := template.New("template").Parse(string(c))
 	if err != nil {
 	if err != nil {
@@ -132,3 +146,18 @@ func SystemErrorPage404(w http.ResponseWriter) {
 		Data:   nil,
 		Data:   nil,
 	})
 	})
 }
 }
+
+func UrlToArray(url string) []string {
+	url_buff := url
+	if len(url_buff) >= 1 && url_buff[:1] == "/" {
+		url_buff = url_buff[1:]
+	}
+	if len(url_buff) >= 1 && url_buff[len(url_buff)-1:] == "/" {
+		url_buff = url_buff[:len(url_buff)-1]
+	}
+	if url_buff == "" {
+		return []string{}
+	} else {
+		return strings.Split(url_buff, "/")
+	}
+}