Andrea Fazzi 6 éve
szülő
commit
941110abfe

+ 83 - 50
handlers/handlers.go

@@ -1,6 +1,7 @@
 package api
 package api
 
 
 import (
 import (
+	"encoding/json"
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
 	"log"
 	"log"
@@ -17,6 +18,17 @@ import (
 	"github.com/gorilla/sessions"
 	"github.com/gorilla/sessions"
 )
 )
 
 
+type User struct {
+	Name  string
+	Admin bool
+}
+
+type PathPattern struct {
+	Path         string
+	RedirectPath string
+	Methods      []string
+}
+
 var (
 var (
 	signingKey    = []byte("secret")
 	signingKey    = []byte("secret")
 	store         = sessions.NewCookieStore([]byte("something-very-secret"))
 	store         = sessions.NewCookieStore([]byte("something-very-secret"))
@@ -29,21 +41,20 @@ var (
 		ErrorHandler:  onError,
 		ErrorHandler:  onError,
 	})
 	})
 
 
-	crud []string = []string{"add", "show", "update", "delete"}
+	patterns []PathPattern = []PathPattern{
+		PathPattern{"/%s", "", []string{"GET"}},
+		PathPattern{"/%s/{id}", "", []string{"GET"}},
+		PathPattern{"/%s/add/", "/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}},
+		PathPattern{"/%s/{id}/update", "/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show", []string{"GET", "POST"}},
+		PathPattern{"/%s/{id}/delete", "/%s?format=html&tpl_layout=base&tpl_content=%s", []string{"DELETE"}},
+	}
 )
 )
 
 
-type User struct {
-	Name  string
-	Admin bool
-}
-
 // Generate CRUD handlers
 // Generate CRUD handlers
 func generateHandler(r *mux.Router, base string) {
 func generateHandler(r *mux.Router, base string) {
-	r.Handle(fmt.Sprintf("/%s", base), jwtMiddleware.Handler(recoverHandler(generalHandler(base, fmt.Sprintf("/%s", base))))).Methods("GET")
-	r.Handle(fmt.Sprintf("/%s/{id}", base), jwtMiddleware.Handler(recoverHandler(generalHandler(base, fmt.Sprintf("/%s/{id}", base))))).Methods("GET")
-	r.Handle(fmt.Sprintf("/%s/add/", base), jwtMiddleware.Handler(recoverHandler(generalHandler(base, fmt.Sprintf("/%s/add/", base))))).Methods("GET", "POST")
-	r.Handle(fmt.Sprintf("/%s/{id}/update", base), jwtMiddleware.Handler(recoverHandler(generalHandler(base, fmt.Sprintf("/%s/{id}/update", base))))).Methods("GET", "POST")
-	r.Handle(fmt.Sprintf("/%s/{id}/delete", base), jwtMiddleware.Handler(recoverHandler(generalHandler(base, fmt.Sprintf("/%s/{id}/delete", base))))).Methods("POST")
+	for _, pattern := range patterns {
+		r.Handle(fmt.Sprintf(pattern.Path, base), jwtMiddleware.Handler(recoverHandler(modelHandler(base, fmt.Sprintf(pattern.Path, base), pattern.RedirectPath)))).Methods(pattern.Methods...)
+	}
 }
 }
 
 
 func Handlers() *mux.Router {
 func Handlers() *mux.Router {
@@ -58,7 +69,7 @@ func Handlers() *mux.Router {
 
 
 	r.Handle("/", jwtMiddleware.Handler(recoverHandler(dashboardHandler())))
 	r.Handle("/", jwtMiddleware.Handler(recoverHandler(dashboardHandler())))
 
 
-	// Generate handlers
+	// Generate model handlers
 
 
 	for _, model := range []string{"teachers", "activities"} {
 	for _, model := range []string{"teachers", "activities"} {
 		generateHandler(r, model)
 		generateHandler(r, model)
@@ -113,57 +124,79 @@ func recoverHandler(next http.Handler) http.Handler {
 	return http.HandlerFunc(fn)
 	return http.HandlerFunc(fn)
 }
 }
 
 
-func generalHandler(base, path string) http.Handler {
+func modelHandler(base, path, redirectPath string) http.Handler {
 	fn := func(w http.ResponseWriter, r *http.Request) {
 	fn := func(w http.ResponseWriter, r *http.Request) {
 		var (
 		var (
 			ok     bool
 			ok     bool
 			getFn  orm.GetFn
 			getFn  orm.GetFn
 			postFn orm.PostFn
 			postFn orm.PostFn
 		)
 		)
-		if r.Method == "GET" {
+
+		switch r.Method {
+
+		case "GET":
 			getFn, ok = orm.Get[path]
 			getFn, ok = orm.Get[path]
-		} else {
+			if !ok {
+				renderer.Render[r.URL.Query()["format"][0]](w, r, fmt.Errorf("Can't find ORM function for path %s!", path))
+			}
+			data, err := getFn(mux.Vars(r))
+			if err != nil {
+				renderer.Render[r.URL.Query()["format"][0]](w, r, err)
+			} else {
+				renderer.Render[r.URL.Query()["format"][0]](w, r, data, r.URL.Query())
+			}
+
+		case "POST":
 			postFn, ok = orm.Post[path]
 			postFn, ok = orm.Post[path]
-		}
-		if !ok {
-			renderer.Render[r.URL.Query()["format"][0]](w, r, fmt.Errorf("Can't find ORM function for path %s!", path))
-		} else {
-			if r.Method == "GET" {
-				data, err := getFn(mux.Vars(r))
-				if err != nil {
-					renderer.Render[r.URL.Query()["format"][0]](w, r, err)
-				} else {
-					renderer.Render[r.URL.Query()["format"][0]](w, r, data, r.URL.Query())
-				}
+			if !ok {
+				renderer.Render[r.URL.Query()["format"][0]](w, r, fmt.Errorf("Can't find ORM function for path %s!", path))
+			}
+			data, err := postFn(mux.Vars(r), r)
+			if err != nil {
+				renderer.Render["html"](w, r, err)
 			} else {
 			} else {
-				data, err := postFn(mux.Vars(r), r)
-				if err != nil {
-					renderer.Render["html"](w, r, err)
+				if mux.Vars(r)["id"] != "" {
+					http.Redirect(w, r,
+						fmt.Sprintf(
+							"/%s/%s?format=html&tpl_layout=base&tpl_content=%s_show",
+							base,
+							mux.Vars(r)["id"],
+							base,
+						),
+						http.StatusSeeOther,
+					)
 				} else {
 				} else {
-					if mux.Vars(r)["id"] != "" {
-						http.Redirect(w, r,
-							fmt.Sprintf(
-								"/%s/%s?format=html&tpl_layout=base&tpl_content=%s_show",
-								base,
-								mux.Vars(r)["id"],
-								base,
-							),
-							http.StatusSeeOther,
-						)
-					} else {
-						http.Redirect(w, r,
-							fmt.Sprintf(
-								"/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show",
-								base,
-								data.GetID(),
-								base,
-							),
-							http.StatusSeeOther,
-						)
-					}
+					http.Redirect(w, r,
+						fmt.Sprintf(
+							"/%s/%d?format=html&tpl_layout=base&tpl_content=%s_show",
+							base,
+							data.GetID(),
+							base,
+						),
+						http.StatusSeeOther,
+					)
+				}
+
+			}
 
 
+		case "DELETE":
+			postFn, ok = orm.Post[path]
+			if !ok {
+				renderer.Render[r.URL.Query().Get("format")](w, r, fmt.Errorf("Can't find ORM function for path %s!", path))
+			}
+			_, err := postFn(mux.Vars(r), r)
+			if err != nil {
+				renderer.Render["html"](w, r, err)
+			} else {
+				var data struct {
+					RedirectUrl string `json:"redirect_url"`
 				}
 				}
+				data.RedirectUrl = fmt.Sprintf(redirectPath, base, base)
+
+				w.Header().Set("Content-Type", "application/json")
+				json.NewEncoder(w).Encode(data)
 			}
 			}
+
 		}
 		}
 	}
 	}
 
 

+ 8 - 17
orm/activity.go

@@ -171,22 +171,13 @@ func CreateActivity(activity *Activity) (*Activity, error) {
 	return activity, nil
 	return activity, nil
 }
 }
 
 
-func DeleteActivity(activity *Activity) error {
-	if err := DB().Delete(activity).Error; err != nil {
-		return err
+func DeleteActivity(args map[string]string, r *http.Request) (IDer, error) {
+	activity, err := GetActivity(args)
+	if err != nil {
+		return nil, err
 	}
 	}
-	return nil
+	if err := DB().Unscoped().Delete(activity.(*Activity)).Error; err != nil {
+		return nil, err
+	}
+	return activity.(*Activity), nil
 }
 }
-
-// func (a *Activity) AfterSave(tx *gorm.DB) error {
-// 	var act Activity
-// 	if err := DB().Preload("Teacher").Preload("Subject").Preload("Class").First(&act, a.ID).Error; err != nil {
-// 		return err
-// 	}
-
-// 	log.Println(a.ID)
-// 	if err := tx.Model(a).Update("name", fmt.Sprintf("%s %s %dh", act.Class.Name, act.Subject.Name, act.Hours)).Error; err != nil {
-// 		return err
-// 	}
-// 	return nil
-// }

+ 1 - 0
orm/credential.go

@@ -12,6 +12,7 @@ type Credential struct {
 	Surname         string
 	Surname         string
 	Username        string
 	Username        string
 	Password        string
 	Password        string
+	PlainPassword   string
 	Email           string
 	Email           string
 	TelephoneNumber string
 	TelephoneNumber string
 }
 }

+ 2 - 0
orm/orm.go

@@ -115,10 +115,12 @@ var (
 	Post map[string]PostFn = map[string]PostFn{
 	Post map[string]PostFn = map[string]PostFn{
 		// Teacher
 		// Teacher
 		"/teachers/{id}/update": UpdateTeacher,
 		"/teachers/{id}/update": UpdateTeacher,
+		"/teachers/{id}/delete": DeleteTeacher,
 		"/teachers/add/":        AddTeacher,
 		"/teachers/add/":        AddTeacher,
 
 
 		// Activity
 		// Activity
 		"/activities/{id}/update": UpdateActivity,
 		"/activities/{id}/update": UpdateActivity,
+		"/activities/{id}/delete": DeleteActivity,
 		"/activities/add/":        AddActivity,
 		"/activities/add/":        AddActivity,
 	}
 	}
 )
 )

+ 32 - 8
orm/orm_test.go

@@ -1,6 +1,7 @@
 package orm
 package orm
 
 
 import (
 import (
+	"strconv"
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
@@ -81,6 +82,35 @@ func (t *testSuite) TestSaveActivity() {
 	}
 	}
 }
 }
 
 
+func (t *testSuite) TestDeleteActivity() {
+	var activities []*Activity
+
+	err := DB().Find(&activities).Error
+	t.Nil(err)
+
+	numActivities := len(activities)
+	activity, err := CreateActivity(
+		&Activity{
+			SubjectID: 1,
+			TeacherID: 1,
+			ClassID:   1,
+		})
+	t.Nil(err)
+
+	err = DB().Find(&activities).Error
+	t.Nil(err)
+
+	t.Equal(numActivities+1, len(activities))
+
+	_, err = DeleteActivity(map[string]string{"id": strconv.Itoa(int(activity.ID))}, nil)
+	t.Nil(err)
+
+	err = DB().Find(&activities).Error
+	t.Nil(err)
+
+	t.Equal(numActivities, len(activities))
+}
+
 func (t *testSuite) TestGetTeacher() {
 func (t *testSuite) TestGetTeacher() {
 	teacher, err := GetTeacher(map[string]string{"id": "1"})
 	teacher, err := GetTeacher(map[string]string{"id": "1"})
 	t.Nil(err)
 	t.Nil(err)
@@ -201,17 +231,11 @@ func (t *testSuite) TestSaveTeacher() {
 }
 }
 
 
 func (t *testSuite) TestCreateDeleteTeacher() {
 func (t *testSuite) TestCreateDeleteTeacher() {
-	teacher := new(Teacher)
-	teacher.Name = "Giovanni"
-	teacher.Surname = "Giacobbe"
-
-	_, err := CreateTeacher(teacher)
+	teacher, err := CreateTeacher(&Teacher{Credential: Credential{Name: "Giovanni", Surname: "GIACOBBE"}})
 	t.Nil(err)
 	t.Nil(err)
 
 
 	if !t.Failed() {
 	if !t.Failed() {
-		teacherFromDb, _ := GetTeacher(map[string]string{"id": "10"})
-		t.Equal("Giovanni", teacherFromDb.(*Teacher).Name)
-		err := DeleteTeacher(teacherFromDb.(*Teacher))
+		_, err = DeleteTeacher(map[string]string{"id": strconv.Itoa(int(teacher.ID))}, nil)
 		t.Nil(err)
 		t.Nil(err)
 		teachers, _ := GetTeachers(map[string]string{})
 		teachers, _ := GetTeachers(map[string]string{})
 		t.Equal(9, len(teachers.([]*Teacher)))
 		t.Equal(9, len(teachers.([]*Teacher)))

+ 12 - 4
orm/teacher.go

@@ -47,6 +47,10 @@ func GetNothing(args map[string]string) (interface{}, error) {
 	return nil, nil
 	return nil, nil
 }
 }
 
 
+func PostNothing(args map[string]string, r *http.Request) (IDer, error) {
+	return nil, nil
+}
+
 func GetTeacher(args map[string]string) (interface{}, error) {
 func GetTeacher(args map[string]string) (interface{}, error) {
 	var teacher Teacher
 	var teacher Teacher
 	if err := DB().First(&teacher, args["id"]).Error; err != nil {
 	if err := DB().First(&teacher, args["id"]).Error; err != nil {
@@ -149,11 +153,15 @@ func CreateTeacher(teacher *Teacher) (*Teacher, error) {
 	return teacher, nil
 	return teacher, nil
 }
 }
 
 
-func DeleteTeacher(teacher *Teacher) error {
-	if err := DB().Delete(teacher).Error; err != nil {
-		return err
+func DeleteTeacher(args map[string]string, r *http.Request) (IDer, error) {
+	teacher, err := GetTeacher(args)
+	if err != nil {
+		return nil, err
 	}
 	}
-	return nil
+	if err := DB().Unscoped().Delete(teacher.(*Teacher)).Error; err != nil {
+		return nil, err
+	}
+	return teacher.(*Teacher), nil
 }
 }
 
 
 func (t *Teacher) GetClasses() ([]*Class, error) {
 func (t *Teacher) GetClasses() ([]*Class, error) {

+ 1 - 1
templates/activities.html.tpl

@@ -30,7 +30,7 @@
       <span class="glyphicon glyphicon-briefcase"></span>
       <span class="glyphicon glyphicon-briefcase"></span>
       {{$activity.Subject.Name}}
       {{$activity.Subject.Name}}
       <div class="text-right">
       <div class="text-right">
-	{{if eq $activity.Teacher.ID 0}}
+	{{if not $activity.Teacher}}
 	<small>no docente</small>
 	<small>no docente</small>
 	{{else}}
 	{{else}}
 	<small>{{$activity.Teacher.Surname}}</small>
 	<small>{{$activity.Teacher.Surname}}</small>

+ 1 - 1
templates/activities_show.html.tpl

@@ -3,7 +3,7 @@
 <div class="container">
 <div class="container">
 
 
   <ol class="breadcrumb">
   <ol class="breadcrumb">
-    <li><a href="/activities?{{query "base" "activities"}}">Attività</a></li>
+    <li><a href="/activities?{{query "tpl_layout" "base" "tpl_content" "activities"}}">Attività</a></li>
     <li class="active"><a href="#">{{.Data.Subject.Name}} {{.Data.Class.Name}} {{.Data.Hours}}h</a></li>
     <li class="active"><a href="#">{{.Data.Subject.Name}} {{.Data.Class.Name}} {{.Data.Hours}}h</a></li>
   </ol>
   </ol>
 
 

+ 8 - 0
templates/teachers.html.tpl

@@ -34,12 +34,20 @@
       <span class="glyphicon glyphicon-user"></span>
       <span class="glyphicon glyphicon-user"></span>
       {{$teacher.Name}} {{$teacher.Surname}}
       {{$teacher.Name}} {{$teacher.Surname}}
       <div class="text-right">
       <div class="text-right">
+	{{if $teacher.Classes}}
 	{{range $class := $teacher.Classes}}
 	{{range $class := $teacher.Classes}}
 	<small>{{$class.Name}}</small>
 	<small>{{$class.Name}}</small>
 	{{end}}
 	{{end}}
+	{{else}}
+	<small>no classi</small>
+	{{end}}
+	{{if $teacher.Subjects}}
 	{{range $subject := $teacher.Subjects}}
 	{{range $subject := $teacher.Subjects}}
 	<small>{{$subject.Name}}</small>
 	<small>{{$subject.Name}}</small>
 	{{end}}
 	{{end}}
+	{{else}}
+	<small>no materie</small>
+        {{end}}
       </div>
       </div>
     </a>
     </a>
     {{end}}
     {{end}}