Make all types, functions and variables private
This commit is contained in:
parent
fa717894a5
commit
62a6f87203
|
@ -1,14 +1,14 @@
|
|||
package main
|
||||
|
||||
type Author struct {
|
||||
type author struct {
|
||||
Key string
|
||||
Name string
|
||||
Email string
|
||||
|
||||
Notebooks []*Notebook
|
||||
Notebooks []*notebook
|
||||
}
|
||||
|
||||
var PublicAuthor = &Author{
|
||||
var publicAuthor = &author{
|
||||
Key: "public",
|
||||
Name: "Anonymous",
|
||||
Email: "anonymous@stick.app",
|
||||
|
|
42
config.go
42
config.go
|
@ -10,38 +10,38 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
AuthorAccessRead = 0
|
||||
AuthorAccessCheck = 1
|
||||
AuthorAccessWrite = 2
|
||||
authorAccessRead = 0
|
||||
authorAccessCheck = 1
|
||||
authorAccessWrite = 2
|
||||
)
|
||||
|
||||
const DefaultConfigPath = "~/.config/stick/stick.yml"
|
||||
const defaultConfigPath = "~/.config/stick/stick.yml"
|
||||
|
||||
type Config struct {
|
||||
type config struct {
|
||||
Salt string
|
||||
Serve string
|
||||
|
||||
Authors []*AuthorConfig
|
||||
Notebooks []*NotebookConfig
|
||||
Authors []*authorConfig
|
||||
Notebooks []*notebookConfig
|
||||
|
||||
Debug bool
|
||||
}
|
||||
|
||||
type AuthorConfig struct {
|
||||
type authorConfig struct {
|
||||
Email string
|
||||
Name string
|
||||
}
|
||||
|
||||
type NotebookConfig struct {
|
||||
type notebookConfig struct {
|
||||
Label string
|
||||
Repo string
|
||||
Serve map[string]int
|
||||
}
|
||||
|
||||
func ReadConfigFile(path string) (*Config, error) {
|
||||
func readConfigFile(path string) (*config, error) {
|
||||
var err error
|
||||
if path == "" {
|
||||
path = DefaultConfigPath
|
||||
path = defaultConfigPath
|
||||
}
|
||||
path, err = expandPath(path)
|
||||
if err != nil {
|
||||
|
@ -53,18 +53,18 @@ func ReadConfigFile(path string) (*Config, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
c := &Config{}
|
||||
c := &config{}
|
||||
err = c.load(data)
|
||||
return c, err
|
||||
}
|
||||
|
||||
func ReadConfigData(data []byte) (*Config, error) {
|
||||
c := &Config{}
|
||||
func readConfigData(data []byte) (*config, error) {
|
||||
c := &config{}
|
||||
err := c.load(data)
|
||||
return c, err
|
||||
}
|
||||
|
||||
func (c *Config) load(data []byte) error {
|
||||
func (c *config) load(data []byte) error {
|
||||
var config map[string]interface{}
|
||||
err := yaml.Unmarshal(data, &config)
|
||||
if err != nil {
|
||||
|
@ -82,7 +82,7 @@ func (c *Config) load(data []byte) error {
|
|||
if as, ok := config["authors"]; ok {
|
||||
auths := as.(map[interface{}]interface{})
|
||||
for aemail, aname := range auths {
|
||||
c.Authors = append(c.Authors, &AuthorConfig{Email: aemail.(string), Name: aname.(string)})
|
||||
c.Authors = append(c.Authors, &authorConfig{Email: aemail.(string), Name: aname.(string)})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ func (c *Config) load(data []byte) error {
|
|||
}
|
||||
sort.Strings(labels)
|
||||
for _, label := range labels {
|
||||
nbconfig := &NotebookConfig{Label: label, Serve: make(map[string]int)}
|
||||
nbconfig := ¬ebookConfig{Label: label, Serve: make(map[string]int)}
|
||||
|
||||
nbo := nbs[label].(map[interface{}]interface{})
|
||||
for option, v := range nbo {
|
||||
|
@ -106,18 +106,18 @@ func (c *Config) load(data []byte) error {
|
|||
for _, nbsvi := range nbsv {
|
||||
switch nbsvi.(type) {
|
||||
case string:
|
||||
nbconfig.Serve[nbsvi.(string)] = AuthorAccessRead
|
||||
nbconfig.Serve[nbsvi.(string)] = authorAccessRead
|
||||
case map[interface{}]interface{}:
|
||||
nbsvx := nbsvi.(map[interface{}]interface{})
|
||||
for nbsvxi, nbsvxa := range nbsvx {
|
||||
access := -1
|
||||
switch nbsvxa.(string) {
|
||||
case "read":
|
||||
access = AuthorAccessRead
|
||||
access = authorAccessRead
|
||||
case "check":
|
||||
access = AuthorAccessCheck
|
||||
access = authorAccessCheck
|
||||
case "write":
|
||||
access = AuthorAccessWrite
|
||||
access = authorAccessWrite
|
||||
}
|
||||
if access == -1 {
|
||||
return errors.New(fmt.Sprintf("invalid serve configuration: invalid access level specified for %s (%s should be read/check/write)", nbsvxi, nbsvxa.(string)))
|
||||
|
|
|
@ -29,7 +29,7 @@ notebooks:
|
|||
- read@stick.rocketnine.space
|
||||
`)
|
||||
|
||||
c, err := ReadConfigData(configData)
|
||||
c, err := readConfigData(configData)
|
||||
if err != nil {
|
||||
t.Errorf("failed to load config data: %+v", err)
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ notebooks:
|
|||
t.Errorf("failed to read config option Salt: expected %s, got %s", "xXxN4CLxXx", c.Salt)
|
||||
}
|
||||
|
||||
expectedAuthors := []*AuthorConfig{
|
||||
expectedAuthors := []*authorConfig{
|
||||
{Email: "read@stick.rocketnine.space", Name: "Read Access"},
|
||||
{Email: "check@stick.rocketnine.space", Name: "Check Access"},
|
||||
{Email: "write@stick.rocketnine.space", Name: "Write Access"}}
|
||||
|
@ -54,13 +54,13 @@ notebooks:
|
|||
}
|
||||
}
|
||||
if found != 1 {
|
||||
t.Errorf("failed to read config option Author: expected 1 %v, got %d", expectedAuthor, found)
|
||||
t.Errorf("failed to read config option author: expected 1 %v, got %d", expectedAuthor, found)
|
||||
}
|
||||
}
|
||||
|
||||
expectedNotebooks := []*NotebookConfig{
|
||||
{Label: "Test Notebook A", Repo: "/home/stick/repo/a", Serve: map[string]int{"read@stick.rocketnine.space": AuthorAccessRead, "write@stick.rocketnine.space": AuthorAccessWrite}},
|
||||
{Label: "Test Notebook B", Repo: "/home/stick/repo/b", Serve: map[string]int{"check@stick.rocketnine.space": AuthorAccessCheck, "read@stick.rocketnine.space": AuthorAccessRead}}}
|
||||
expectedNotebooks := []*notebookConfig{
|
||||
{Label: "Test Notebook A", Repo: "/home/stick/repo/a", Serve: map[string]int{"read@stick.rocketnine.space": authorAccessRead, "write@stick.rocketnine.space": authorAccessWrite}},
|
||||
{Label: "Test Notebook B", Repo: "/home/stick/repo/b", Serve: map[string]int{"check@stick.rocketnine.space": authorAccessCheck, "read@stick.rocketnine.space": authorAccessRead}}}
|
||||
for _, expectedNotebook := range expectedNotebooks {
|
||||
found := 0
|
||||
for _, notebook := range c.Notebooks {
|
||||
|
@ -69,7 +69,7 @@ notebooks:
|
|||
}
|
||||
}
|
||||
if found != 1 {
|
||||
t.Errorf("failed to read config option Notebook: expected 1 %v, got %d", expectedNotebook, found)
|
||||
t.Errorf("failed to read config option notebook: expected 1 %v, got %d", expectedNotebook, found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
git.go
4
git.go
|
@ -4,7 +4,7 @@ import (
|
|||
git "github.com/go-git/go-git/v5"
|
||||
)
|
||||
|
||||
func InitializeRepository(worktree string, cloneurl string) (*git.Repository, error) {
|
||||
func initializeRepository(worktree string, cloneurl string) (*git.Repository, error) {
|
||||
if cloneurl == "" {
|
||||
return git.PlainInit(worktree, false)
|
||||
}
|
||||
|
@ -14,6 +14,6 @@ func InitializeRepository(worktree string, cloneurl string) (*git.Repository, er
|
|||
})
|
||||
}
|
||||
|
||||
func LoadRepository(worktree string) (*git.Repository, error) {
|
||||
func loadRepository(worktree string) (*git.Repository, error) {
|
||||
return git.PlainOpen(worktree)
|
||||
}
|
||||
|
|
10
main.go
10
main.go
|
@ -27,7 +27,7 @@ Global options:
|
|||
`
|
||||
|
||||
var (
|
||||
stick *Stick
|
||||
stick *server
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -47,7 +47,7 @@ func main() {
|
|||
command := flag.Arg(0)
|
||||
switch command {
|
||||
case "init":
|
||||
Initialize(configPath, debug)
|
||||
initialize(configPath, debug)
|
||||
|
||||
path := flag.Arg(1)
|
||||
if path == "" {
|
||||
|
@ -57,14 +57,14 @@ func main() {
|
|||
|
||||
cloneURL := flag.Arg(2)
|
||||
|
||||
_, err := InitializeRepository(path, cloneURL)
|
||||
_, err := initializeRepository(path, cloneURL)
|
||||
if err != nil {
|
||||
panic(errors.Wrap(err, "failed to initialize notebook"))
|
||||
}
|
||||
|
||||
fmt.Println("notebook initialized")
|
||||
case "resolve":
|
||||
Initialize(configPath, debug)
|
||||
initialize(configPath, debug)
|
||||
|
||||
path := flag.Arg(1)
|
||||
if path == "" {
|
||||
|
@ -74,7 +74,7 @@ func main() {
|
|||
|
||||
// TODO: initialize editor to resolve conflict
|
||||
case "serve":
|
||||
Initialize(configPath, debug)
|
||||
initialize(configPath, debug)
|
||||
|
||||
address := flag.Arg(1)
|
||||
if stick.Config.Serve == "" && address == "" {
|
||||
|
|
26
note.go
26
note.go
|
@ -9,19 +9,19 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const OptionsReaderSize = 512
|
||||
const optionsReaderSize = 512
|
||||
|
||||
var (
|
||||
startsWithCheckbox = regexp.MustCompile(`^\[[ *xX]].*`)
|
||||
noteHeader = []byte("[//]: # (")
|
||||
)
|
||||
|
||||
type ListItem struct {
|
||||
type listItem struct {
|
||||
Indent int
|
||||
Text string
|
||||
}
|
||||
|
||||
type Note struct {
|
||||
type note struct {
|
||||
ID string
|
||||
Label string
|
||||
ModifiedAt int64
|
||||
|
@ -29,7 +29,7 @@ type Note struct {
|
|||
Body string
|
||||
}
|
||||
|
||||
func OptionsReader(r io.Reader) []string {
|
||||
func optionsReader(r io.Reader) []string {
|
||||
lr := io.LimitReader(r, 9)
|
||||
hdr := make([]byte, 9)
|
||||
|
||||
|
@ -45,7 +45,7 @@ func OptionsReader(r io.Reader) []string {
|
|||
var (
|
||||
opts []string
|
||||
|
||||
buf = make([]byte, OptionsReaderSize)
|
||||
buf = make([]byte, optionsReaderSize)
|
||||
opt []byte
|
||||
)
|
||||
|
||||
|
@ -83,7 +83,7 @@ ReadOptions:
|
|||
return opts
|
||||
}
|
||||
|
||||
func Options(body string) []string {
|
||||
func options(body string) []string {
|
||||
if len(body) <= 10 || body[0:9] != "[//]: # (" {
|
||||
return nil
|
||||
}
|
||||
|
@ -102,12 +102,12 @@ func Options(body string) []string {
|
|||
return options
|
||||
}
|
||||
|
||||
func PrintListItems(list []*ListItem, bullet string, capitalize bool) string {
|
||||
func printListItems(list []*listItem, bullet string, capitalize bool) string {
|
||||
var indents []int
|
||||
for _, item := range list {
|
||||
indents = append(indents, item.Indent)
|
||||
}
|
||||
indents = UniqueInts(indents)
|
||||
indents = uniqueInts(indents)
|
||||
sort.Ints(indents)
|
||||
|
||||
offsets := make(map[int]int, len(indents))
|
||||
|
@ -187,11 +187,11 @@ func PrintListItems(list []*ListItem, bullet string, capitalize bool) string {
|
|||
return out
|
||||
}
|
||||
|
||||
func SortListItems(body string, capitalize bool) string {
|
||||
func sortListItems(body string, capitalize bool) string {
|
||||
var (
|
||||
line string
|
||||
newBody string
|
||||
list []*ListItem
|
||||
list []*listItem
|
||||
bullet string
|
||||
)
|
||||
|
||||
|
@ -201,7 +201,7 @@ func SortListItems(body string, capitalize bool) string {
|
|||
thisIndent := strings.IndexAny(line, "*-")
|
||||
if thisIndent == -1 || len(line) == (thisIndent+1) || line[thisIndent+1:thisIndent+2] != " " {
|
||||
if list != nil {
|
||||
newBody += PrintListItems(list, bullet, capitalize)
|
||||
newBody += printListItems(list, bullet, capitalize)
|
||||
list = nil
|
||||
}
|
||||
|
||||
|
@ -211,12 +211,12 @@ func SortListItems(body string, capitalize bool) string {
|
|||
bullet = line[thisIndent : thisIndent+1]
|
||||
}
|
||||
|
||||
list = append(list, &ListItem{Indent: thisIndent, Text: strings.TrimSpace(line[thisIndent+2:])})
|
||||
list = append(list, &listItem{Indent: thisIndent, Text: strings.TrimSpace(line[thisIndent+2:])})
|
||||
}
|
||||
}
|
||||
|
||||
if list != nil {
|
||||
newBody += PrintListItems(list, bullet, capitalize)
|
||||
newBody += printListItems(list, bullet, capitalize)
|
||||
}
|
||||
|
||||
return newBody
|
||||
|
|
78
notebook.go
78
notebook.go
|
@ -10,15 +10,15 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
/*n, err := LoadNotebook("/home/trevor/stick/personal/")
|
||||
/*n, err := loadNotebook("/home/trevor/stick/personal/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
log.Print(time.Unix(n.Created(), 0))
|
||||
log.Print(time.Unix(n.created(), 0))
|
||||
log.Print(time.Unix(n.Modified(), 0))
|
||||
|
||||
err = n.Upload()
|
||||
err = n.upload()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), git.ErrNonFastForwardUpdate.Error()) {
|
||||
log.Println("conflict while pushing")
|
||||
|
@ -26,7 +26,7 @@ if err != nil {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
err = n.Download()
|
||||
err = n.download()
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), git.ErrNonFastForwardUpdate.Error()) {
|
||||
log.Println("conflict while updating")
|
||||
|
@ -36,9 +36,9 @@ if err != nil {
|
|||
}
|
||||
}*/
|
||||
|
||||
const DefaultSubmoduleDepth = 10
|
||||
const defaultSubmoduleDepth = 10
|
||||
|
||||
type Notebook struct {
|
||||
type notebook struct {
|
||||
ID string
|
||||
Label string
|
||||
Serve map[string]int `json:"-"`
|
||||
|
@ -46,8 +46,8 @@ type Notebook struct {
|
|||
Repository *git.Repository `json:"-"`
|
||||
}
|
||||
|
||||
func (n *Notebook) getNote(id string, fetchBody bool) *Note {
|
||||
file := n.File(id)
|
||||
func (n *notebook) getNote(id string, fetchBody bool) *note {
|
||||
file := n.file(id)
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -60,9 +60,9 @@ func (n *Notebook) getNote(id string, fetchBody bool) *Note {
|
|||
}
|
||||
|
||||
cIter, err := r.Log(&git.LogOptions{From: ref.Hash(), Order: git.LogOrderCommitterTime, FileName: &file.Name})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
note := &Note{ID: id}
|
||||
note := ¬e{ID: id}
|
||||
|
||||
err = cIter.ForEach(func(c *object.Commit) error {
|
||||
note.ModifiedAt = c.Author.When.Unix()
|
||||
|
@ -70,7 +70,7 @@ func (n *Notebook) getNote(id string, fetchBody bool) *Note {
|
|||
|
||||
return storer.ErrStop
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
note.Label = file.Name
|
||||
if strings.HasSuffix(strings.ToLower(note.Label), ".md") {
|
||||
|
@ -88,40 +88,40 @@ func (n *Notebook) getNote(id string, fetchBody bool) *Note {
|
|||
return note
|
||||
}
|
||||
|
||||
func (n *Notebook) allNotes() map[string]*Note {
|
||||
func (n *notebook) allNotes() map[string]*note {
|
||||
r := n.Repository
|
||||
|
||||
ref, err := r.Head()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
commit, err := r.CommitObject(ref.Hash())
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
tree, err := commit.Tree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
notes := make(map[string]*Note)
|
||||
notes := make(map[string]*note)
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
noteID := hash(f.Name)
|
||||
note := n.getNote(noteID, true)
|
||||
notes[noteID] = note
|
||||
return nil
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
return notes
|
||||
}
|
||||
|
||||
type ServedNotebook struct {
|
||||
*Notebook
|
||||
Notes map[string]*Note
|
||||
type servedNotebook struct {
|
||||
*notebook
|
||||
Notes map[string]*note
|
||||
}
|
||||
|
||||
func NewNotebook(worktree string, cloneurl string) (*Notebook, error) {
|
||||
func newNotebook(worktree string, cloneurl string) (*notebook, error) {
|
||||
var err error
|
||||
|
||||
n := &Notebook{}
|
||||
n.Repository, err = InitializeRepository(worktree, cloneurl)
|
||||
n := ¬ebook{}
|
||||
n.Repository, err = initializeRepository(worktree, cloneurl)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to initialize repository")
|
||||
}
|
||||
|
@ -129,11 +129,11 @@ func NewNotebook(worktree string, cloneurl string) (*Notebook, error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
func LoadNotebook(worktree string) (*Notebook, error) {
|
||||
func loadNotebook(worktree string) (*notebook, error) {
|
||||
var err error
|
||||
|
||||
n := &Notebook{}
|
||||
n.Repository, err = LoadRepository(worktree)
|
||||
n := ¬ebook{}
|
||||
n.Repository, err = loadRepository(worktree)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load repository")
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ func LoadNotebook(worktree string) (*Notebook, error) {
|
|||
return n, nil
|
||||
}
|
||||
|
||||
func (n *Notebook) Created() int64 {
|
||||
func (n *notebook) created() int64 {
|
||||
head, err := n.Repository.Head()
|
||||
if err != nil {
|
||||
return 0 // No commits yet
|
||||
|
@ -167,20 +167,20 @@ func (n *Notebook) Created() int64 {
|
|||
return commit.Author.When.Unix()
|
||||
}
|
||||
|
||||
func (n *Notebook) Download() error {
|
||||
func (n *notebook) download() error {
|
||||
w, err := n.Repository.Worktree()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read worktree")
|
||||
}
|
||||
|
||||
return w.Pull(&git.PullOptions{RemoteName: "origin", RecurseSubmodules: DefaultSubmoduleDepth})
|
||||
return w.Pull(&git.PullOptions{RemoteName: "origin", RecurseSubmodules: defaultSubmoduleDepth})
|
||||
}
|
||||
|
||||
func (n *Notebook) Upload() error {
|
||||
func (n *notebook) upload() error {
|
||||
return n.Repository.Push(&git.PushOptions{RemoteName: "origin"})
|
||||
}
|
||||
|
||||
func (n *Notebook) File(id string) *object.File {
|
||||
func (n *notebook) file(id string) *object.File {
|
||||
var file *object.File
|
||||
|
||||
ref, err := n.Repository.Head()
|
||||
|
@ -189,10 +189,10 @@ func (n *Notebook) File(id string) *object.File {
|
|||
}
|
||||
|
||||
commit, err := n.Repository.CommitObject(ref.Hash())
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
tree, err := commit.Tree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
if hash(f.Name) == id {
|
||||
|
@ -202,21 +202,21 @@ func (n *Notebook) File(id string) *object.File {
|
|||
|
||||
return nil
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
func (n *Notebook) Compact() {
|
||||
func (n *notebook) compact() {
|
||||
tree, err := n.Repository.Worktree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
wtroot := tree.Filesystem.Root()
|
||||
|
||||
cmd := exec.Command("git", "-C", tree.Filesystem.Root(), "gc", "--aggressive", "--prune=now")
|
||||
err = cmd.Run()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
n.Repository, err = LoadRepository(wtroot)
|
||||
CheckError(err)
|
||||
n.Repository, err = loadRepository(wtroot)
|
||||
checkError(err)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ func registerSignalHandlers() {
|
|||
log.Println("Compacting notebooks...")
|
||||
stick.NotebooksLock.Lock()
|
||||
for _, notebook := range stick.Notebooks {
|
||||
notebook.Compact()
|
||||
notebook.compact()
|
||||
}
|
||||
stick.NotebooksLock.Unlock()
|
||||
log.Println("Compacted notebooks")
|
||||
|
|
|
@ -7,47 +7,47 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Stick struct {
|
||||
Config *Config
|
||||
type server struct {
|
||||
Config *config
|
||||
|
||||
Authors map[string]*Author
|
||||
Authors map[string]*author
|
||||
AuthorsLock sync.RWMutex
|
||||
|
||||
Notebooks map[string]*Notebook
|
||||
Notebooks map[string]*notebook
|
||||
NotebooksLock sync.RWMutex
|
||||
}
|
||||
|
||||
func Initialize(configPath string, debug bool) {
|
||||
func initialize(configPath string, debug bool) {
|
||||
var err error
|
||||
|
||||
stick = &Stick{}
|
||||
stick.Config, err = ReadConfigFile(configPath)
|
||||
CheckError(err)
|
||||
stick = &server{}
|
||||
stick.Config, err = readConfigFile(configPath)
|
||||
checkError(err)
|
||||
|
||||
stick.Config.Debug = debug
|
||||
StickSalt = []byte(stick.Config.Salt)
|
||||
stickSalt = []byte(stick.Config.Salt)
|
||||
|
||||
stick.loadAuthors()
|
||||
stick.loadNotebooks()
|
||||
}
|
||||
|
||||
func (s *Stick) loadAuthors() {
|
||||
func (s *server) loadAuthors() {
|
||||
// TODO: Allow reloading config
|
||||
|
||||
stick.Authors = map[string]*Author{}
|
||||
for _, author := range stick.Config.Authors {
|
||||
stick.Authors[hash(author.Email)] = &Author{Key: hash(author.Email), Email: author.Email, Name: author.Name}
|
||||
stick.Authors = map[string]*author{}
|
||||
for _, a := range stick.Config.Authors {
|
||||
stick.Authors[hash(a.Email)] = &author{Key: hash(a.Email), Email: a.Email, Name: a.Name}
|
||||
}
|
||||
|
||||
stick.Authors["public"] = PublicAuthor
|
||||
stick.Authors["public"] = publicAuthor
|
||||
}
|
||||
|
||||
func (s *Stick) loadNotebooks() {
|
||||
func (s *server) loadNotebooks() {
|
||||
// TODO: Allow reloading config
|
||||
|
||||
stick.Notebooks = make(map[string]*Notebook)
|
||||
stick.Notebooks = make(map[string]*notebook)
|
||||
for _, nbconfig := range stick.Config.Notebooks {
|
||||
notebook, err := LoadNotebook(nbconfig.Repo)
|
||||
notebook, err := loadNotebook(nbconfig.Repo)
|
||||
if err != nil {
|
||||
log.Fatal(errors.Wrapf(err, "failed to load %s", nbconfig.Repo))
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ func (s *Stick) loadNotebooks() {
|
|||
stick.Notebooks[hash(nbconfig.Label)] = notebook
|
||||
}
|
||||
|
||||
var author *Author
|
||||
var author *author
|
||||
for _, notebook := range stick.Notebooks {
|
||||
for serveauth := range notebook.Serve {
|
||||
author = stick.getAuthor(serveauth)
|
||||
|
@ -84,7 +84,7 @@ func (s *Stick) loadNotebooks() {
|
|||
|
||||
}
|
||||
|
||||
func (s *Stick) getAuthor(key string) *Author {
|
||||
func (s *server) getAuthor(key string) *author {
|
||||
s.AuthorsLock.RLock()
|
||||
defer s.AuthorsLock.RUnlock()
|
||||
|
||||
|
@ -95,7 +95,7 @@ func (s *Stick) getAuthor(key string) *Author {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Stick) getNotebook(key string) *Notebook {
|
||||
func (s *server) getNotebook(key string) *notebook {
|
||||
s.NotebooksLock.RLock()
|
||||
defer s.NotebooksLock.RUnlock()
|
||||
|
8
utils.go
8
utils.go
|
@ -10,7 +10,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
var StickSalt []byte
|
||||
var stickSalt []byte
|
||||
|
||||
func expandPath(path string) (string, error) {
|
||||
if !strings.HasPrefix(path, "~") {
|
||||
|
@ -25,7 +25,7 @@ func expandPath(path string) (string, error) {
|
|||
return homedir + path[1:], nil
|
||||
}
|
||||
|
||||
func UniqueInts(input []int) []int {
|
||||
func uniqueInts(input []int) []int {
|
||||
u := make([]int, 0, len(input))
|
||||
m := make(map[int]bool)
|
||||
|
||||
|
@ -54,7 +54,7 @@ func hashWithSalt(str string, salt []byte) string {
|
|||
}
|
||||
|
||||
func hash(str string) string {
|
||||
return hashWithSalt(str, StickSalt)
|
||||
return hashWithSalt(str, stickSalt)
|
||||
}
|
||||
|
||||
func elapsed(what string) func() {
|
||||
|
@ -64,7 +64,7 @@ func elapsed(what string) func() {
|
|||
}
|
||||
}
|
||||
|
||||
func CheckError(err error) {
|
||||
func checkError(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
164
web.go
164
web.go
|
@ -22,23 +22,23 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
SocketBufferSize = 10
|
||||
SocketPingPeriod = 2 * time.Minute
|
||||
SocketReadTimeout = 5 * time.Minute
|
||||
SocketWriteTimeout = 20 * time.Second
|
||||
socketBufferSize = 10
|
||||
socketPingPeriod = 2 * time.Minute
|
||||
socketReadTimeout = 5 * time.Minute
|
||||
socketWriteTimeout = 20 * time.Second
|
||||
)
|
||||
|
||||
type StickSocket struct {
|
||||
type stickSocket struct {
|
||||
ID int
|
||||
Status int
|
||||
Conn *websocket.Conn
|
||||
Author *Author
|
||||
Author *author
|
||||
|
||||
writebuffer chan *map[string]interface{}
|
||||
writebufferwg sync.WaitGroup
|
||||
}
|
||||
|
||||
func (s *StickSocket) Write(m *map[string]interface{}) {
|
||||
func (s *stickSocket) Write(m *map[string]interface{}) {
|
||||
if s.Status == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ func (s *StickSocket) Write(m *map[string]interface{}) {
|
|||
s.writebuffer <- m
|
||||
}
|
||||
|
||||
func (s *StickSocket) handleRead() {
|
||||
func (s *stickSocket) handleRead() {
|
||||
var (
|
||||
message []byte
|
||||
c *StickSocketCommand
|
||||
c *stickSocketCommand
|
||||
err error
|
||||
)
|
||||
|
||||
|
@ -65,9 +65,9 @@ func (s *StickSocket) handleRead() {
|
|||
log.Printf("WS read %d %s", s.ID, message)
|
||||
}
|
||||
|
||||
c = &StickSocketCommand{}
|
||||
c = &stickSocketCommand{}
|
||||
err = json.Unmarshal(message, &c.Data)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
if command, ok := c.Data["command"]; ok {
|
||||
c.Command = command.(string)
|
||||
|
@ -115,22 +115,22 @@ func (s *StickSocket) handleRead() {
|
|||
if a, ok := c.Notebook.Serve[s.Author.Key]; ok {
|
||||
access = a
|
||||
}
|
||||
if access <= AuthorAccessRead || (access == AuthorAccessCheck && c.Command != "check") {
|
||||
if access <= authorAccessRead || (access == authorAccessCheck && c.Command != "check") {
|
||||
s.Write(socketResponse("fail", "unauthorized"))
|
||||
continue
|
||||
}
|
||||
|
||||
if f, ok := SocketCommands[c.Command]; ok {
|
||||
SocketCommandLock.Lock()
|
||||
if f, ok := socketCommands[c.Command]; ok {
|
||||
socketCommandLock.Lock()
|
||||
s.Write(f(s, c))
|
||||
SocketCommandLock.Unlock()
|
||||
socketCommandLock.Unlock()
|
||||
} else {
|
||||
s.Write(socketResponse("fail", "invalid-command"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StickSocket) handleWrite() {
|
||||
func (s *stickSocket) handleWrite() {
|
||||
var (
|
||||
m *map[string]interface{}
|
||||
out []byte
|
||||
|
@ -144,9 +144,9 @@ func (s *StickSocket) handleWrite() {
|
|||
}
|
||||
|
||||
out, err = json.Marshal(m)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
err = s.Conn.SetWriteDeadline(time.Now().Add(SocketWriteTimeout))
|
||||
err = s.Conn.SetWriteDeadline(time.Now().Add(socketWriteTimeout))
|
||||
if err != nil {
|
||||
go s.Close("failed to set write timeout")
|
||||
continue
|
||||
|
@ -165,16 +165,16 @@ func (s *StickSocket) handleWrite() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *StickSocket) handlePing() {
|
||||
err := s.Conn.SetReadDeadline(time.Now().Add(SocketReadTimeout))
|
||||
func (s *stickSocket) handlePing() {
|
||||
err := s.Conn.SetReadDeadline(time.Now().Add(socketReadTimeout))
|
||||
if err != nil {
|
||||
s.Close("failed to set read timeout")
|
||||
return
|
||||
}
|
||||
|
||||
s.Conn.SetPongHandler(func(string) error { return s.Conn.SetReadDeadline(time.Now().Add(SocketReadTimeout)) })
|
||||
s.Conn.SetPongHandler(func(string) error { return s.Conn.SetReadDeadline(time.Now().Add(socketReadTimeout)) })
|
||||
|
||||
ticker := time.NewTicker(SocketPingPeriod)
|
||||
ticker := time.NewTicker(socketPingPeriod)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
<-ticker.C
|
||||
|
@ -182,7 +182,7 @@ func (s *StickSocket) handlePing() {
|
|||
return
|
||||
}
|
||||
|
||||
err := s.Conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(SocketWriteTimeout))
|
||||
err := s.Conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(socketWriteTimeout))
|
||||
if err != nil {
|
||||
s.Close("failed to ping client")
|
||||
return
|
||||
|
@ -190,9 +190,9 @@ func (s *StickSocket) handlePing() {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *StickSocket) Close(reason string) {
|
||||
WebSocketsLock.Lock()
|
||||
defer WebSocketsLock.Unlock()
|
||||
func (s *stickSocket) Close(reason string) {
|
||||
webSocketsLock.Lock()
|
||||
defer webSocketsLock.Unlock()
|
||||
|
||||
if s.Status == 0 {
|
||||
return
|
||||
|
@ -209,26 +209,26 @@ func (s *StickSocket) Close(reason string) {
|
|||
close(s.writebuffer)
|
||||
|
||||
if s.ID > 0 {
|
||||
delete(WebSockets, s.ID)
|
||||
delete(webSockets, s.ID)
|
||||
}
|
||||
}
|
||||
|
||||
type StickSocketCommand struct {
|
||||
type stickSocketCommand struct {
|
||||
Command string
|
||||
Modified int64
|
||||
Notebook *Notebook
|
||||
Note *Note
|
||||
Notebook *notebook
|
||||
Note *note
|
||||
Data map[string]interface{} // Command JSON from client
|
||||
}
|
||||
|
||||
type StickSocketHandler func(*StickSocket, *StickSocketCommand) *map[string]interface{}
|
||||
type stickSocketHandler func(*stickSocket, *stickSocketCommand) *map[string]interface{}
|
||||
|
||||
var (
|
||||
SocketCommands = map[string]StickSocketHandler{"fetch": webFetch,"edit": webEdit, "check": webCheck, "delete": webDelete}
|
||||
SocketCommandLock sync.Mutex
|
||||
socketCommands = map[string]stickSocketHandler{"fetch": webFetch, "edit": webEdit, "check": webCheck, "delete": webDelete}
|
||||
socketCommandLock sync.Mutex
|
||||
|
||||
WebSockets = make(map[int]*StickSocket)
|
||||
WebSocketsLock sync.RWMutex
|
||||
webSockets = make(map[int]*stickSocket)
|
||||
webSocketsLock sync.RWMutex
|
||||
)
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
|
@ -278,7 +278,7 @@ func webSocketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if a, ok := vars["author"]; ok {
|
||||
auth = a
|
||||
}
|
||||
var author *Author
|
||||
var author *author
|
||||
stick.AuthorsLock.RLock()
|
||||
for stickauthkey, stickauth := range stick.Authors {
|
||||
if stickauthkey == auth {
|
||||
|
@ -288,7 +288,7 @@ func webSocketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
stick.AuthorsLock.RUnlock()
|
||||
|
||||
s := &StickSocket{Status: 1, Conn: conn, Author: author, writebuffer: make(chan *map[string]interface{}, SocketBufferSize)}
|
||||
s := &stickSocket{Status: 1, Conn: conn, Author: author, writebuffer: make(chan *map[string]interface{}, socketBufferSize)}
|
||||
|
||||
go s.handleWrite()
|
||||
go s.handlePing()
|
||||
|
@ -304,16 +304,16 @@ func webSocketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
var (
|
||||
socketID int
|
||||
)
|
||||
WebSocketsLock.Lock()
|
||||
webSocketsLock.Lock()
|
||||
for {
|
||||
socketID = rand.Intn(math.MaxInt32-1) + 1
|
||||
if _, ok := WebSockets[socketID]; !ok {
|
||||
if _, ok := webSockets[socketID]; !ok {
|
||||
s.ID = socketID
|
||||
WebSockets[socketID] = s
|
||||
webSockets[socketID] = s
|
||||
break
|
||||
}
|
||||
}
|
||||
WebSocketsLock.Unlock()
|
||||
webSocketsLock.Unlock()
|
||||
|
||||
if m, ok := vars["modified"]; ok {
|
||||
syncmodified, err = strconv.ParseInt(m, 10, 64)
|
||||
|
@ -341,7 +341,7 @@ func serveWeb() {
|
|||
}
|
||||
}
|
||||
|
||||
func sendNote(ss *StickSocket, notebookID string, noteID string) {
|
||||
func sendNote(ss *stickSocket, notebookID string, noteID string) {
|
||||
response := map[string]interface{}{}
|
||||
response["author"] = ss.Author.Name
|
||||
response["notebookid"] = notebookID
|
||||
|
@ -363,7 +363,7 @@ func sendNote(ss *StickSocket, notebookID string, noteID string) {
|
|||
ss.Write(&response)
|
||||
}
|
||||
|
||||
func sendNotesSince(ss *StickSocket, modified int64) {
|
||||
func sendNotesSince(ss *stickSocket, modified int64) {
|
||||
newModified := modified
|
||||
author := ss.Author
|
||||
|
||||
|
@ -371,18 +371,18 @@ func sendNotesSince(ss *StickSocket, modified int64) {
|
|||
|
||||
response := map[string]interface{}{}
|
||||
response["author"] = author.Name
|
||||
response["notebooks"] = map[string]*ServedNotebook{}
|
||||
response["notebooks"] = map[string]*servedNotebook{}
|
||||
response["pinned"] = map[string][]string{}
|
||||
for _, notebook := range author.Notebooks {
|
||||
snb := &ServedNotebook{Notebook: notebook, Notes: make(map[string]*Note)}
|
||||
snb := &servedNotebook{notebook: notebook, Notes: make(map[string]*note)}
|
||||
|
||||
ref, err := notebook.Repository.Head()
|
||||
if err == nil { // Non-empty repository
|
||||
commit, err := notebook.Repository.CommitObject(ref.Hash())
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
tree, err := commit.Tree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
noteID := hash(f.Name)
|
||||
|
@ -398,7 +398,7 @@ func sendNotesSince(ss *StickSocket, modified int64) {
|
|||
|
||||
r, err := f.Reader()
|
||||
if err == nil { // Ignore err
|
||||
opts = OptionsReader(r)
|
||||
opts = optionsReader(r)
|
||||
for _, opt := range opts {
|
||||
if opt == "pin" {
|
||||
response["pinned"].(map[string][]string)[snb.ID] = append(response["pinned"].(map[string][]string)[snb.ID], noteID)
|
||||
|
@ -410,10 +410,10 @@ func sendNotesSince(ss *StickSocket, modified int64) {
|
|||
|
||||
return nil
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
}
|
||||
|
||||
response["notebooks"].(map[string]*ServedNotebook)[snb.ID] = snb
|
||||
response["notebooks"].(map[string]*servedNotebook)[snb.ID] = snb
|
||||
}
|
||||
|
||||
if modified > 0 {
|
||||
|
@ -424,12 +424,12 @@ func sendNotesSince(ss *StickSocket, modified int64) {
|
|||
}
|
||||
|
||||
// Fetch a note
|
||||
func webFetch(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
||||
func webFetch(s *stickSocket, c *stickSocketCommand) *map[string]interface{} {
|
||||
return &map[string]interface{}{"status": "success", "notebookid": c.Notebook.ID, "noteid": c.Note.ID, "note": c.Note}
|
||||
}
|
||||
|
||||
// Edit a note
|
||||
func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
||||
func webEdit(s *stickSocket, c *stickSocketCommand) *map[string]interface{} {
|
||||
if stick.Config.Debug {
|
||||
defer elapsed("webEdit")()
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
optSort := false
|
||||
optList := false
|
||||
|
||||
opts := Options(body)
|
||||
opts := options(body)
|
||||
for _, opt := range opts {
|
||||
switch opt {
|
||||
case "sort":
|
||||
|
@ -461,11 +461,11 @@ func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
}
|
||||
|
||||
if optSort {
|
||||
body = SortListItems(body, optList)
|
||||
body = sortListItems(body, optList)
|
||||
}
|
||||
|
||||
wt, err := c.Notebook.Repository.Worktree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
fileName := ""
|
||||
addNew := false
|
||||
|
@ -481,17 +481,17 @@ func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
if addNew && os.IsExist(err) {
|
||||
return socketResponse("fail", "note-already-exists")
|
||||
} else if !os.IsExist(err) && !os.IsNotExist(err) {
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
}
|
||||
} else {
|
||||
file := c.Notebook.File(c.Note.ID)
|
||||
file := c.Notebook.file(c.Note.ID)
|
||||
if file == nil {
|
||||
return socketResponse("fail", "failed-to-read-note")
|
||||
}
|
||||
fileName = file.Name
|
||||
|
||||
data, err := file.Contents()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
if data == body {
|
||||
// TODO: Send unmodified message
|
||||
|
@ -506,19 +506,19 @@ func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
// Write
|
||||
|
||||
status, err := wt.Status()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
if len(status) > 0 {
|
||||
return socketResponse("fail", "modified-externally")
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(wt.Filesystem.Join(wt.Filesystem.Root(), fileName), []byte(body), 0644)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
// Commit
|
||||
|
||||
_, err = wt.Add(fileName)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
commitMessage := "add"
|
||||
if !addNew {
|
||||
|
@ -532,7 +532,7 @@ func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
if c.Note == nil {
|
||||
c.Note = c.Notebook.getNote(hash(fileName), true)
|
||||
|
@ -546,7 +546,7 @@ func webEdit(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
}
|
||||
|
||||
// Mark/un-mark a checkbox via its item number (index)
|
||||
func webCheck(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
||||
func webCheck(s *stickSocket, c *stickSocketCommand) *map[string]interface{} {
|
||||
if stick.Config.Debug {
|
||||
defer elapsed("webCheck")()
|
||||
}
|
||||
|
@ -558,13 +558,13 @@ func webCheck(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
checkItem = int64(ci.(float64))
|
||||
}
|
||||
|
||||
file := c.Notebook.File(c.Note.ID)
|
||||
file := c.Notebook.file(c.Note.ID)
|
||||
if file == nil {
|
||||
return socketResponse("fail", "failed-to-read-note")
|
||||
}
|
||||
|
||||
data, err := file.Contents()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
// Update
|
||||
|
||||
|
@ -597,10 +597,10 @@ func webCheck(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
}
|
||||
|
||||
wt, err := c.Notebook.Repository.Worktree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
status, err := wt.Status()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
if len(status) > 0 {
|
||||
return socketResponse("fail", "modified-externally")
|
||||
|
@ -609,12 +609,12 @@ func webCheck(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
// Write
|
||||
|
||||
err = ioutil.WriteFile(wt.Filesystem.Join(wt.Filesystem.Root(), file.Name), []byte(data), 0644)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
// Commit
|
||||
|
||||
_, err = wt.Add(file.Name)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
_, err = wt.Commit("update "+file.Name, &git.CommitOptions{
|
||||
Author: &object.Signature{
|
||||
|
@ -623,14 +623,14 @@ func webCheck(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
updateWebSockets(s.Author, c.Notebook.ID, c.Note.ID)
|
||||
return socketResponse("success", "")
|
||||
}
|
||||
|
||||
// Delete a note
|
||||
func webDelete(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
||||
func webDelete(s *stickSocket, c *stickSocketCommand) *map[string]interface{} {
|
||||
if stick.Config.Debug {
|
||||
defer elapsed("webDelete")()
|
||||
}
|
||||
|
@ -639,7 +639,7 @@ func webDelete(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
err error
|
||||
)
|
||||
|
||||
file := c.Notebook.File(c.Note.ID)
|
||||
file := c.Notebook.file(c.Note.ID)
|
||||
if file == nil || file.Name == "" {
|
||||
return socketResponse("fail", "failed-to-read-note")
|
||||
}
|
||||
|
@ -647,22 +647,22 @@ func webDelete(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
// Delete
|
||||
|
||||
wt, err := c.Notebook.Repository.Worktree()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
status, err := wt.Status()
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
if len(status) > 0 {
|
||||
return socketResponse("fail", "modified-externally")
|
||||
}
|
||||
|
||||
err = wt.Filesystem.Remove(file.Name)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
// Commit
|
||||
|
||||
_, err = wt.Add(file.Name)
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
_, err = wt.Commit("delete "+file.Name, &git.CommitOptions{
|
||||
Author: &object.Signature{
|
||||
|
@ -671,7 +671,7 @@ func webDelete(s *StickSocket, c *StickSocketCommand) *map[string]interface{} {
|
|||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
CheckError(err)
|
||||
checkError(err)
|
||||
|
||||
updateWebSockets(s.Author, c.Notebook.ID, "")
|
||||
return socketResponse("success", "")
|
||||
|
@ -681,15 +681,15 @@ func socketResponse(status string, message string) *map[string]interface{} {
|
|||
return &map[string]interface{}{"status": status, "message": message}
|
||||
}
|
||||
|
||||
func updateWebSockets(author *Author, notebookID string, noteID string) {
|
||||
func updateWebSockets(author *author, notebookID string, noteID string) {
|
||||
stick.NotebooksLock.RLock()
|
||||
defer stick.NotebooksLock.RUnlock()
|
||||
|
||||
WebSocketsLock.RLock()
|
||||
defer WebSocketsLock.RUnlock()
|
||||
webSocketsLock.RLock()
|
||||
defer webSocketsLock.RUnlock()
|
||||
|
||||
if noteID == "" {
|
||||
for _, ss := range WebSockets {
|
||||
for _, ss := range webSockets {
|
||||
if ss.Author.Key == author.Key {
|
||||
sendNotesSince(ss, 0)
|
||||
}
|
||||
|
@ -698,7 +698,7 @@ func updateWebSockets(author *Author, notebookID string, noteID string) {
|
|||
return
|
||||
}
|
||||
|
||||
for _, ss := range WebSockets {
|
||||
for _, ss := range webSockets {
|
||||
if ss.Author.Key == author.Key {
|
||||
sendNote(ss, notebookID, noteID)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue