Send updated note when checking/unchecking item

This commit is contained in:
Trevor Slocum 2019-04-08 23:21:40 -07:00
parent d68cdfd8a2
commit 63cb6fbcd3
4 changed files with 149 additions and 162 deletions

View File

@ -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
}

View File

@ -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
View File

@ -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
})

View File

@ -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>&nbsp; ' + modified.getFullYear() + '/' + (modified.getMonth() + 1) + '/' + modified.getDate() + ' ' + ('0' + modified.getHours()).slice(-2) + ':' + ('0' + modified.getMinutes()).slice(-2) + ' &middot; ' + Notebooks[ViewNotebook].ModifiedBy + '</small></div>';
modified = new Date(note.ModifiedAt * 1000);
NoteBody += '<div style="margin-bottom: 7px;"><small>&nbsp; ' + modified.getFullYear() + '/' + (modified.getMonth() + 1) + '/' + modified.getDate() + ' ' + ('0' + modified.getHours()).slice(-2) + ':' + ('0' + modified.getMinutes()).slice(-2) + ' &middot; ' + note.ModifiedBy + '</small></div>';
}
if (note && NoteMode === "view") {