Send updated note when checking/unchecking item
This commit is contained in:
parent
d68cdfd8a2
commit
63cb6fbcd3
9
note.go
9
note.go
|
@ -1,8 +1,9 @@
|
|||
package main
|
||||
|
||||
type Note struct {
|
||||
ID string
|
||||
Label string
|
||||
Modified int64
|
||||
Body string
|
||||
ID string
|
||||
Label string
|
||||
ModifiedAt int64
|
||||
ModifiedBy string
|
||||
Body string
|
||||
}
|
||||
|
|
59
notebook.go
59
notebook.go
|
@ -1,6 +1,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/src-d/go-git.v4"
|
||||
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
||||
|
@ -43,11 +45,48 @@ type Notebook struct {
|
|||
Repository *git.Repository `json:"-"`
|
||||
}
|
||||
|
||||
func (n *Notebook) getNote(id string) *Note {
|
||||
file := n.File(id)
|
||||
if file == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
r := n.Repository
|
||||
|
||||
ref, err := r.Head()
|
||||
CheckError(err)
|
||||
|
||||
cIter, err := r.Log(&git.LogOptions{From: ref.Hash(), Order: git.LogOrderCommitterTime, FileName: &file.Name})
|
||||
CheckError(err)
|
||||
|
||||
note := &Note{ID: id}
|
||||
|
||||
err = cIter.ForEach(func(c *object.Commit) error {
|
||||
note.ModifiedAt = c.Author.When.Unix()
|
||||
note.ModifiedBy = c.Author.Name
|
||||
|
||||
return storer.ErrStop
|
||||
})
|
||||
CheckError(err)
|
||||
|
||||
// TODO: Custom note labels defined inside notes?
|
||||
note.Label = file.Name
|
||||
if strings.HasSuffix(strings.ToLower(note.Label), ".md") {
|
||||
note.Label = note.Label[0 : len(note.Label)-3]
|
||||
}
|
||||
note.Label = strings.Title(strings.Replace(note.Label, "-", " ", -1))
|
||||
|
||||
note.Body, err = file.Contents()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return note
|
||||
}
|
||||
|
||||
type ServedNotebook struct {
|
||||
*Notebook
|
||||
ModifiedAt int64
|
||||
ModifiedBy string
|
||||
Notes map[string]*Note
|
||||
Notes map[string]*Note
|
||||
}
|
||||
|
||||
func NewNotebook(worktree string, cloneurl string) (*Notebook, error) {
|
||||
|
@ -100,20 +139,6 @@ func (n *Notebook) Created() int64 {
|
|||
return commit.Author.When.Unix()
|
||||
}
|
||||
|
||||
func (n *Notebook) Modified() int64 {
|
||||
head, err := n.Repository.Head()
|
||||
if err != nil {
|
||||
return 0 // No commits yet
|
||||
}
|
||||
|
||||
commit, err := n.Repository.CommitObject(head.Hash())
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return commit.Author.When.Unix()
|
||||
}
|
||||
|
||||
func (n *Notebook) Download() error {
|
||||
w, err := n.Repository.Worktree()
|
||||
if err != nil {
|
||||
|
|
229
web.go
229
web.go
|
@ -2,13 +2,13 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
|
@ -46,7 +46,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
|
|||
var (
|
||||
auth string
|
||||
nbid string
|
||||
note string
|
||||
noteID string
|
||||
modified int64
|
||||
title string
|
||||
body string
|
||||
|
@ -74,7 +74,7 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
|
|||
nbid = nb
|
||||
}
|
||||
if n, ok := vars["note"]; ok {
|
||||
note = n
|
||||
noteID = n
|
||||
}
|
||||
|
||||
if m, ok := vars["modified"]; ok {
|
||||
|
@ -102,71 +102,25 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
|
|||
continue
|
||||
}
|
||||
|
||||
if note == "" {
|
||||
note = strings.Replace(strings.ToLower(title), " ", "-", -1)
|
||||
if !strings.HasSuffix(note, ".md") {
|
||||
note += ".md"
|
||||
}
|
||||
fileName := ""
|
||||
addNew := false
|
||||
if noteID == "" {
|
||||
addNew = true
|
||||
|
||||
// Write
|
||||
|
||||
wt, err := notebook.Repository.Worktree()
|
||||
CheckError(err)
|
||||
|
||||
status, err := wt.Status()
|
||||
CheckError(err)
|
||||
|
||||
if len(status) > 0 {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = wt.Filesystem.Stat(note)
|
||||
if os.IsExist(err) {
|
||||
writeStatus(w, "exists")
|
||||
return
|
||||
} else if !os.IsNotExist(err) {
|
||||
CheckError(err)
|
||||
}
|
||||
|
||||
filew, err := wt.Filesystem.OpenFile(note, syscall.O_CREAT|syscall.O_WRONLY, 0644)
|
||||
CheckError(err)
|
||||
|
||||
_, err = filew.Write([]byte(body))
|
||||
CheckError(err)
|
||||
|
||||
err = filew.Close()
|
||||
CheckError(err)
|
||||
|
||||
// Commit
|
||||
|
||||
_, err = wt.Add(note)
|
||||
CheckError(err)
|
||||
|
||||
commit, err := wt.Commit("add "+note, &git.CommitOptions{
|
||||
Author: &object.Signature{
|
||||
Name: author.Name,
|
||||
Email: DefaultAuthorEmail,
|
||||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
CheckError(err)
|
||||
|
||||
obj, err := notebook.Repository.CommitObject(commit)
|
||||
CheckError(err)
|
||||
|
||||
if obj == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
fileName = strings.Replace(strings.ToLower(title), " ", "-", -1)
|
||||
if !strings.HasSuffix(fileName, ".md") {
|
||||
fileName += ".md"
|
||||
}
|
||||
} else {
|
||||
if notebook.Modified() != modified {
|
||||
writeStatus(w, "modified")
|
||||
file := notebook.File(noteID)
|
||||
if file == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
fileName = file.Name
|
||||
|
||||
file := notebook.File(note)
|
||||
if file == nil {
|
||||
note := notebook.getNote(noteID)
|
||||
if note == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
@ -179,49 +133,67 @@ func editHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// Write
|
||||
|
||||
wt, err := notebook.Repository.Worktree()
|
||||
CheckError(err)
|
||||
|
||||
status, err := wt.Status()
|
||||
CheckError(err)
|
||||
|
||||
if len(status) > 0 {
|
||||
writeStatus(w, "fail")
|
||||
if note.ModifiedAt != modified {
|
||||
writeStatus(w, "modified")
|
||||
return
|
||||
}
|
||||
}
|
||||
if fileName == "" {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
||||
filew, err := wt.Filesystem.OpenFile(file.Name, syscall.O_WRONLY, 0644)
|
||||
// Write
|
||||
|
||||
wt, err := notebook.Repository.Worktree()
|
||||
CheckError(err)
|
||||
|
||||
status, err := wt.Status()
|
||||
CheckError(err)
|
||||
|
||||
if len(status) > 0 {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
||||
_, err = wt.Filesystem.Stat(fileName)
|
||||
if addNew && os.IsExist(err) {
|
||||
writeStatus(w, "exists")
|
||||
return
|
||||
} else if !addNew && os.IsNotExist(err) {
|
||||
writeStatus(w, "fail")
|
||||
} else if !os.IsExist(err) && !os.IsNotExist(err) {
|
||||
CheckError(err)
|
||||
}
|
||||
|
||||
_, err = filew.Write([]byte(body))
|
||||
CheckError(err)
|
||||
err = ioutil.WriteFile(wt.Filesystem.Join(wt.Filesystem.Root(), fileName), []byte(body), 0644)
|
||||
CheckError(err)
|
||||
|
||||
err = filew.Close()
|
||||
CheckError(err)
|
||||
// Commit
|
||||
|
||||
// Commit
|
||||
_, err = wt.Add(fileName)
|
||||
CheckError(err)
|
||||
|
||||
_, err = wt.Add(file.Name)
|
||||
CheckError(err)
|
||||
commitMessage := "add"
|
||||
if !addNew {
|
||||
commitMessage = "update"
|
||||
}
|
||||
|
||||
commit, err := wt.Commit("update "+file.Name, &git.CommitOptions{
|
||||
Author: &object.Signature{
|
||||
Name: author.Name,
|
||||
Email: DefaultAuthorEmail,
|
||||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
CheckError(err)
|
||||
commit, err := wt.Commit(commitMessage+" "+fileName, &git.CommitOptions{
|
||||
Author: &object.Signature{
|
||||
Name: author.Name,
|
||||
Email: DefaultAuthorEmail,
|
||||
When: time.Now(),
|
||||
},
|
||||
})
|
||||
CheckError(err)
|
||||
|
||||
obj, err := notebook.Repository.CommitObject(commit)
|
||||
CheckError(err)
|
||||
obj, err := notebook.Repository.CommitObject(commit)
|
||||
CheckError(err)
|
||||
|
||||
if obj == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
if obj == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
||||
writeStatus(w, "success")
|
||||
|
@ -243,7 +215,7 @@ func checkHandler(w http.ResponseWriter, r *http.Request) {
|
|||
var (
|
||||
auth string
|
||||
nbid string
|
||||
note string
|
||||
noteID string
|
||||
checkmodified int64
|
||||
checknum int64
|
||||
err error
|
||||
|
@ -270,7 +242,7 @@ func checkHandler(w http.ResponseWriter, r *http.Request) {
|
|||
nbid = nb
|
||||
}
|
||||
if n, ok := vars["note"]; ok {
|
||||
note = n
|
||||
noteID = n
|
||||
}
|
||||
|
||||
if m, ok := vars["modified"]; ok {
|
||||
|
@ -291,16 +263,23 @@ func checkHandler(w http.ResponseWriter, r *http.Request) {
|
|||
continue
|
||||
}
|
||||
|
||||
if notebook.Modified() != checkmodified {
|
||||
writeStatus(w, "modified")
|
||||
return
|
||||
}
|
||||
|
||||
file := notebook.File(note)
|
||||
file := notebook.File(noteID)
|
||||
if file == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
||||
note := notebook.getNote(noteID)
|
||||
if note == nil {
|
||||
writeStatus(w, "fail")
|
||||
return
|
||||
}
|
||||
|
||||
if note.ModifiedAt != checkmodified {
|
||||
writeStatus(w, "modified")
|
||||
return
|
||||
}
|
||||
|
||||
data, err := file.Contents()
|
||||
CheckError(err)
|
||||
|
||||
|
@ -348,13 +327,7 @@ func checkHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// Write
|
||||
|
||||
filew, err := wt.Filesystem.OpenFile(file.Name, syscall.O_WRONLY, 0644)
|
||||
CheckError(err)
|
||||
|
||||
_, err = filew.Write([]byte(data))
|
||||
CheckError(err)
|
||||
|
||||
err = filew.Close()
|
||||
err = ioutil.WriteFile(wt.Filesystem.Join(wt.Filesystem.Root(), file.Name), []byte(data), 0644)
|
||||
CheckError(err)
|
||||
|
||||
// Commit
|
||||
|
@ -379,7 +352,14 @@ func checkHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
writeStatus(w, "success")
|
||||
response := map[string]interface{}{}
|
||||
response["status"] = "success"
|
||||
response["note"] = notebook.getNote(noteID)
|
||||
|
||||
resp, err := json.Marshal(response)
|
||||
CheckError(err)
|
||||
|
||||
_, _ = w.Write(resp)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -397,9 +377,8 @@ func syncHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
var (
|
||||
auth string
|
||||
syncmodified int64
|
||||
nbmodified int64
|
||||
err error
|
||||
syncmodified int64
|
||||
)
|
||||
|
||||
if a, ok := vars["author"]; ok {
|
||||
|
@ -430,13 +409,9 @@ func syncHandler(w http.ResponseWriter, r *http.Request) {
|
|||
response["author"] = author.Name
|
||||
response["notebooks"] = map[string]*ServedNotebook{}
|
||||
for _, notebook := range author.Notebooks {
|
||||
nbmodified = notebook.Modified()
|
||||
|
||||
if syncmodified > 0 && syncmodified <= nbmodified {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: Only send modified notes
|
||||
_ = syncmodified
|
||||
|
||||
r := notebook.Repository
|
||||
config, _ := notebook.Repository.Worktree()
|
||||
_ = config
|
||||
|
@ -450,22 +425,10 @@ func syncHandler(w http.ResponseWriter, r *http.Request) {
|
|||
tree, err := commit.Tree()
|
||||
CheckError(err)
|
||||
|
||||
snb := &ServedNotebook{Notebook: notebook, ModifiedAt: nbmodified, ModifiedBy: commit.Author.Name, Notes: make(map[string]*Note)}
|
||||
|
||||
snb := &ServedNotebook{Notebook: notebook, Notes: make(map[string]*Note)}
|
||||
err = tree.Files().ForEach(func(f *object.File) error {
|
||||
note := &Note{ID: hash(f.Name), Modified: nbmodified}
|
||||
|
||||
// TODO: Custom note labels defined inside notes?
|
||||
note.Label = f.Name
|
||||
if strings.HasSuffix(strings.ToLower(note.Label), ".md") {
|
||||
note.Label = note.Label[0 : len(note.Label)-3]
|
||||
}
|
||||
note.Label = strings.Title(strings.Replace(note.Label, "-", " ", -1))
|
||||
|
||||
// TODO: Send note modified
|
||||
note.Body, err = f.Contents()
|
||||
|
||||
snb.Notes[note.ID] = note
|
||||
noteID := hash(f.Name)
|
||||
snb.Notes[noteID] = notebook.getNote(noteID)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
|
|
@ -133,7 +133,7 @@ function saveNote() {
|
|||
|
||||
var url;
|
||||
if (ViewNote !== "") {
|
||||
url = window.location.href.split("#")[0] + "e/" + AuthKey + "/" + ViewNotebook + "/" + ViewNote + "/" + Notebooks[ViewNotebook].Notes[ViewNote].Modified;
|
||||
url = window.location.href.split("#")[0] + "e/" + AuthKey + "/" + ViewNotebook + "/" + ViewNote + "/" + Notebooks[ViewNotebook].Notes[ViewNote].ModifiedAt;
|
||||
} else {
|
||||
url = window.location.href.split("#")[0] + "e/" + AuthKey + "/" + ViewNotebook;
|
||||
postdata["title"] = $('#editNoteTitle').val();
|
||||
|
@ -186,14 +186,12 @@ function checkItem(item) {
|
|||
|
||||
$.ajax({
|
||||
dataType: 'json',
|
||||
url: window.location.href.split("#")[0] + "c/" + AuthKey + "/" + notebook.ID + "/" + note.ID + "/" + Notebooks[ViewNotebook].Notes[ViewNote].Modified + "/" + item
|
||||
url: window.location.href.split("#")[0] + "c/" + AuthKey + "/" + notebook.ID + "/" + note.ID + "/" + Notebooks[ViewNotebook].Notes[ViewNote].ModifiedAt + "/" + item
|
||||
})
|
||||
.done(function (data) {
|
||||
if (data.status && data.status === "success") {
|
||||
// TODO: Fetch only updated note
|
||||
getNotes().then(function () {
|
||||
render();
|
||||
});
|
||||
Notebooks[ViewNotebook].Notes[ViewNote] = data.note;
|
||||
render();
|
||||
} else {
|
||||
failedToCheckItem(item);
|
||||
}
|
||||
|
@ -280,8 +278,8 @@ function render() {
|
|||
NoteBody += '</div>';
|
||||
|
||||
if (NoteMode === "view" && note) {
|
||||
modified = new Date(Notebooks[ViewNotebook].ModifiedAt * 1000);
|
||||
NoteBody += '<div style="margin-bottom: 7px;"><small> ' + modified.getFullYear() + '/' + (modified.getMonth() + 1) + '/' + modified.getDate() + ' ' + ('0' + modified.getHours()).slice(-2) + ':' + ('0' + modified.getMinutes()).slice(-2) + ' · ' + Notebooks[ViewNotebook].ModifiedBy + '</small></div>';
|
||||
modified = new Date(note.ModifiedAt * 1000);
|
||||
NoteBody += '<div style="margin-bottom: 7px;"><small> ' + modified.getFullYear() + '/' + (modified.getMonth() + 1) + '/' + modified.getDate() + ' ' + ('0' + modified.getHours()).slice(-2) + ':' + ('0' + modified.getMinutes()).slice(-2) + ' · ' + note.ModifiedBy + '</small></div>';
|
||||
}
|
||||
|
||||
if (note && NoteMode === "view") {
|
||||
|
|
Loading…
Reference in New Issue