package main import ( "encoding/json" "io/ioutil" "log" "os" "path/filepath" "time" ) //a Procedure is a alphanumerical string lessthan 128 bytes. //when messages comes in we need to differentiate what Procedure is this in. //default Procedure is where command can happen //where the Procedure is stored, // in sessions/openID.json //if there is no such file, we are in default Procedure. //First Procedure is to record user's name, email, and phone number. // for individual Procedure // Procedure/Procedurename/openID.json var sessionDir = "sessions" //where to find the procedure state information var ProcedureDir = "procedure" //openIDSession openID user's session type openIDSession struct { Procedure string `json:"Procedure"` //name of the current current process, alphanumerical CreateAt int32 `json:"CreateAt"` //when is this session created UpdateAt int32 `json:"UpdateAt"` //when is this session updated Expire int32 `json:"Expire"` //unix timestamp of when this Procedure expires } //read sessions/openID.json to check whether its a Procedure for ongoing dialog func getCurrentSesssion(openID string) (result openIDSession, err error) { path := getSessionPath(openID) log.Printf("read session from %s\r\n", path) body, err := ioutil.ReadFile(path) if err != nil { //read file error if isFileExist(path) { log.Println("Error session reading " + path) } return //empty and expired session } err = json.Unmarshal(body, &result) if err != nil { log.Printf("Session Content [path=%s] not correct: ", path) } //we don't check Expire, we give the caller full control on //how to deal wiht expired session return } func writeSession(openid string, ss openIDSession) (err error) { path := getSessionPath(openid) r, err := json.Marshal(ss) if err == nil { err = ioutil.WriteFile(path, r, 0600) if err != nil { log.Printf("Error writing session %s: \r\n %s \r\n", openid, r) log.Println(err) } else { log.Println("write session to " + path) } } else { log.Printf("Error encoding session %s ", openid) log.Println(err) } return } //create if not available func setSessionProcedure(openID, procedure string, expireAfter int32) (updatedSession openIDSession, err error) { s, err := getCurrentSesssion(openID) now := int32(time.Now().Unix()) if s.CreateAt == 0 { s.CreateAt = now } s.UpdateAt = now s.Procedure = procedure s.Expire = now + expireAfter err = writeSession(openID, s) return s, err } func isExpired(timestamp int32) bool { now := int32(time.Now().Unix()) return now > timestamp } func getSessionPath(openID string) (path string) { path = sessionDir + string(os.PathSeparator) + openID + ".json" ensurePathExist(path) return path } func getProcedurePath(openID, ProcedureName string) (path string) { path = ProcedureDir + string(os.PathSeparator) + ProcedureName + string(os.PathSeparator) + openID + ".json" ensurePathExist(path) return } func ensurePathExist(path string) { d := filepath.Dir(path) if !isFileExist(d) { log.Println("Creating path [" + d + "]") os.MkdirAll(d, 0700) } } func deleteSession(openID string) { path := getSessionPath(openID) if isFileExist(path) { err := os.Remove(path) if err != nil { log.Println(err) } else { log.Println("delete session :" + path) } } }