暫無描述

account.go 5.4KB

    package main import ( "encoding/json" "errors" "fmt" "io/ioutil" "os" "path/filepath" "strings" "time" ) const ( publishDateLayout = "200601021504" ) type Account struct { Username string `json:username` Passphrase string `json:passphrase` } func getAccounts() ([]Account, error) { file := UserFile // Check to see if the file exists if _, err := os.Stat(file); os.IsNotExist(err) { return []Account{}, nil } // Open the file fi, err := os.Open(file) if err != nil { return nil, err } // Read all of its contents raw, err := ioutil.ReadAll(fi) if len(raw) == 0 { return []Account{}, nil } // Translate the JSON to internal structures var accounts []Account err = json.Unmarshal(raw, &accounts) if err != nil { return nil, err } fi.Close() return accounts, nil } func (a *Account) Validate() (bool, error) { file := UserFile // Determine if the "users" file exists // Attempt to create the file if it does not if _, err := os.Stat(file); os.IsNotExist(err) { _, err = os.Create(file) if err != nil { return false, err } } // Get a list of current accounts accounts, err := getAccounts() if err != nil { return false, err } // Search if an account and passphrase match is found for _, x := range accounts { if x.Username == a.Username && x.Passphrase == a.Passphrase { return true, nil } } return false, nil } func (a *Account) Create() error { // Ensure there are no accounts of that name already valid, err := a.Validate() if err != nil { return err } if valid { return errors.New("Account already exists") } // Create directory structure baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) paths := []string{"content", "blog", "calendar"} for _, p := range paths { err = os.MkdirAll(baseDir+s+userDir+s+p, 0755) if err != nil { return err } } // Add the account to all of the accounts accounts, err := getAccounts() if err != nil { return err } accounts = append(accounts, *a) // Create user entry in "users" file // Marshal the JSON marshalled, err := json.Marshal(accounts) if err != nil { return err } // Write to the file fi, err := os.OpenFile(UserFile, os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { return err } _, err = fi.Write(marshalled) if err != nil { return err } fi.Close() return nil } func (a *Account) Delete() error { // Ensure there are no accounts of that name already valid, err := a.Validate() if err != nil { return err } if !valid { return errors.New("Account does not exist") } // Remove user entry in "users" file accounts, err := getAccounts() if err != nil { return err } for i, account := range accounts { if account.Username == a.Username { accounts = append(accounts[:i], accounts[i+1:]...) break } } marshalled, err := json.Marshal(accounts) if err != nil { return err } // Write to the file fi, err := os.OpenFile(UserFile, os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { return err } _, err = fi.Write(marshalled) if err != nil { return err } fi.Close() // Delete directory structure baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) err = os.RemoveAll(baseDir + s + userDir) if err != nil { return err } return nil } func (a *Account) Add(content, filename string, file []byte) (string, error) { if filename == "" { return "", errors.New("Missing filename") } valid, err := a.Validate() if err != nil { return "", err } if !valid { return "", errors.New("Account does not exist") } // Get basic information needed baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) // Create new content directory if necessary if content == "" { content = fmt.Sprintf("%x", hash(userDir+time.Now().Format(publishDateLayout), salt())) } // Create new content directory contentPath := baseDir + s + userDir + s + "content" + s + content if _, err := os.Stat(contentPath); os.IsNotExist(err) { err = os.MkdirAll(contentPath, 0755) if err != nil { return "", err } } // Check if filename already exists filePath := contentPath + s + filename if _, err := os.Stat(filePath); os.IsExist(err) { return filePath, err } // Write file to content directory fi, err := os.OpenFile(filePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) if err != nil { return filePath, err } _, err = fi.Write(file) if err != nil { return filePath, err } fi.Close() return filePath, nil } func (a *Account) Publish(title, content string, date time.Time) error { valid, err := a.Validate() if err != nil { return err } if !valid { return errors.New("Account does not exist") } prettyTitle := strings.ToLower(strings.Replace(title, " ", "-", -1)) baseDir := os.Getenv("LOOP_DATA") userDir := strings.ToLower(a.Username) s := string(filepath.Separator) contentPath := baseDir + s + userDir + s + "content" + s + content publishPath := baseDir + s + userDir + s + "blog" + s + date.Format(publishDateLayout) + "-" + prettyTitle // Check if the content exists if _, err := os.Stat(contentPath); os.IsNotExist(err) { return err } // Check if symlink already exists if _, err := os.Stat(publishPath); os.IsExist(err) { return err } // Create symbolic link in "blog" directory referencing content directory err = os.Symlink(contentPath, publishPath) if err != nil { return err } return nil }