branch bow-v2-go updated (5353481 -> a4fa61d)
This is an automated email from the git hooks/post-receive script. New change to branch bow-v2-go in repository bow. See https://gitlab.nuiton.org/chorem/bow.git from 5353481 ajout de valeur par default dans la base ajout du support de orderby, orderdesc et first en parametre de recherche new a4fa61d debut implantation opensearch - sauvegarde ok - moteur de recherche ok - recherche par tags ok The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit a4fa61db4e4f1afe0ec53fb61b4ef5dfa20814e6 Author: Benjamin <poussin@codelutin.com> Date: Sun Apr 19 23:00:55 2020 +0200 debut implantation opensearch - sauvegarde ok - moteur de recherche ok - recherche par tags ok Amelioration des erreurs pour avoir une stack d'appel Summary of changes: pkg/constant/const.go | 49 +++++++++++++++++++++- pkg/http/actionResource.go | 80 +++++++++++++++++++++++++++++++++++- pkg/http/bookmarkResource.go | 51 ++++++++++++----------- pkg/http/router.go | 4 +- pkg/repository/bookmarkRepository.go | 9 ++-- pkg/repository/database.go | 14 ++++++- pkg/repository/userRepository.go | 6 ++- pkg/utils/error.go | 36 ++++++++++------ pkg/utils/utils.go | 17 ++++++++ web/public/index.html | 1 + web/public/opensearch.xml | 11 +++++ web/src/components/SearchInput.vue | 6 +-- web/src/views/BookmarkEdit.vue | 49 +++++++++++++++++++--- 13 files changed, 275 insertions(+), 58 deletions(-) create mode 100644 pkg/utils/utils.go create mode 100644 web/public/opensearch.xml -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch bow-v2-go in repository bow. See https://gitlab.nuiton.org/chorem/bow.git commit a4fa61db4e4f1afe0ec53fb61b4ef5dfa20814e6 Author: Benjamin <poussin@codelutin.com> Date: Sun Apr 19 23:00:55 2020 +0200 debut implantation opensearch - sauvegarde ok - moteur de recherche ok - recherche par tags ok Amelioration des erreurs pour avoir une stack d'appel --- pkg/constant/const.go | 49 +++++++++++++++++++++- pkg/http/actionResource.go | 80 +++++++++++++++++++++++++++++++++++- pkg/http/bookmarkResource.go | 51 ++++++++++++----------- pkg/http/router.go | 4 +- pkg/repository/bookmarkRepository.go | 9 ++-- pkg/repository/database.go | 14 ++++++- pkg/repository/userRepository.go | 6 ++- pkg/utils/error.go | 36 ++++++++++------ pkg/utils/utils.go | 17 ++++++++ web/public/index.html | 1 + web/public/opensearch.xml | 11 +++++ web/src/components/SearchInput.vue | 6 +-- web/src/views/BookmarkEdit.vue | 49 +++++++++++++++++++--- 13 files changed, 275 insertions(+), 58 deletions(-) diff --git a/pkg/constant/const.go b/pkg/constant/const.go index 5f3ce80..df4069b 100644 --- a/pkg/constant/const.go +++ b/pkg/constant/const.go @@ -36,6 +36,11 @@ WithCount indique de retourner le nombre d'occurrence de ce tag */ const WithCount = "with-count" +/* +Action query parameter name for tags search +*/ +const Action = "action" + /* Tags query parameter name for tags search */ @@ -47,7 +52,7 @@ Fulltext query parameter name for fulltext search const Fulltext = "fulltext" /* -Fulltext query parameter name for fulltext search +Query query parameter name for fulltext search */ const Query = "query" @@ -56,6 +61,11 @@ ID query parameter name for id search */ const ID = "id" +/* +URI query parameter name for uri search +*/ +const URI = "uri" + /* OrderBy query parameter name for select order sorting */ @@ -69,4 +79,39 @@ const OrderDesc = "orderdesc" /* First query parameter name first result */ -const First = "first" \ No newline at end of file +const First = "first" + +/* +Save string action to save bookmark +*/ +const Save = "search.add" + +/* +RedirectAlias string action to redirect to alias (private or public) +*/ +const RedirectAlias = "search.alias" + +/* +SuggestionAlias string action to suggest alias (private) +*/ +const SuggestionAlias = "suggestion.alias" + +/* +SearchFulltext string action to fulltext search in all bookmarks +*/ +const SearchFulltext = "search.fulltext" + +/* +SuggestionFulltext string action to suggest url from fulltext search in all alias +*/ +const SuggestionFulltext = "suggestion.fulltext" + +/* +SearchTag string action to search on tag in all bookmarks +*/ +const SearchTag = "search.tag" + +/* +SuggestionTag string action to suggest url from tag in all alias +*/ +const SuggestionTag = "suggestion.tag" diff --git a/pkg/http/actionResource.go b/pkg/http/actionResource.go index 470e4d9..631f9be 100644 --- a/pkg/http/actionResource.go +++ b/pkg/http/actionResource.go @@ -1,9 +1,87 @@ package http import ( + "fmt" "net/http" + "strings" + + "gitlab.chorem.org/chorem/bow/pkg/constant" + "gitlab.chorem.org/chorem/bow/pkg/model" ) +func getOrEmpty(args []string, i int) string { + result := "" + if len(args) > i { + result = args[i] + } + + return result +} + +var actions = map [string]func(w http.ResponseWriter, r *http.Request, ask string) { + constant.Save: func(w http.ResponseWriter, r *http.Request, ask string) { + args := strings.Split(ask, "|") + uri := getOrEmpty(args, 0) + description := getOrEmpty(args, 1) + tags := getOrEmpty(args, 2) + privatealias := getOrEmpty(args, 3) + publicalias := getOrEmpty(args, 4) + lang := getOrEmpty(args, 5) + + // FIXME parametrer l'url + url := fmt.Sprintf("http://localhost:8080/edit/new?uri=%s&description=%s&tags=%s&privatealias=%s&publicalias=%s&lang=%s", uri, description, tags, privatealias, publicalias, lang) + http.Redirect(w, r, url, http.StatusFound) + }, + constant.RedirectAlias: func(w http.ResponseWriter, r *http.Request, ask string) { + // TODO recherche dans les alias prives + http.Redirect(w, r, "TODO", http.StatusFound) + }, + constant.SuggestionAlias: func(w http.ResponseWriter, r *http.Request, ask string) { + // renvoyer les couple alias/uri/description? pour l'affichage en suggest + //http.Redirect(w, r, uri, http.StatusFound) + }, + constant.SearchFulltext: func(w http.ResponseWriter, r *http.Request, ask string) { + url := fmt.Sprintf("http://localhost:8080/?fulltext=%s", ask) + http.Redirect(w, r, url, http.StatusFound) + }, + constant.SuggestionFulltext: func(w http.ResponseWriter, r *http.Request, ask string) { + // renvoyer les couple uri/description? pour l'affichage en suggest + //http.Redirect(w, r, uri, http.StatusFound) + }, + constant.SearchTag: func(w http.ResponseWriter, r *http.Request, ask string) { + url := fmt.Sprintf("http://localhost:8080/?tags=%s", ask) + http.Redirect(w, r, url, http.StatusFound) + }, + constant.SuggestionTag: func(w http.ResponseWriter, r *http.Request, ask string) { + // renvoyer les couple uri/description? pour l'affichage en suggest + //http.Redirect(w, r, uri, http.StatusFound) + }} + func doActions(w http.ResponseWriter, r *http.Request) { - + currentUser := r.Context().Value(constant.User).(model.BowUser) + + query := r.URL.Query() + ask := query.Get(constant.Action) + + // l'action a faire + var todo string + for _, a := range currentUser.Actions { + prefix := a.Prefix + if prefix == "" { + todo = a.Action + } else if strings.HasPrefix(ask, prefix) { + todo = a.Action + ask = ask[len(prefix):] + break + } + } + + toCall := actions[todo] + if toCall != nil { + toCall(w, r, ask) + } else { + uri := strings.Replace(todo, "{searchTerms}", ask, -1) + http.Redirect(w, r, uri, http.StatusFound) + } + } diff --git a/pkg/http/bookmarkResource.go b/pkg/http/bookmarkResource.go index df8c0a5..0e19afe 100644 --- a/pkg/http/bookmarkResource.go +++ b/pkg/http/bookmarkResource.go @@ -16,24 +16,25 @@ import ( ) func getBookmarks(w http.ResponseWriter, r *http.Request) { - currentUserID := r.Context().Value(constant.User).(model.BowUser) - query := r.URL.Query() - id := query.Get(constant.ID) - tags := query.Get(constant.Tags) - fulltext := query.Get(constant.Fulltext) - - log.Println("query: ", query) - orderBy := query.Get(constant.OrderBy) - orderDesc, err := strconv.ParseBool(query.Get(constant.OrderDesc)) + currentUser := r.Context().Value(constant.User).(model.BowUser) + queryParams := r.URL.Query() + id := queryParams.Get(constant.ID) + uri := queryParams.Get(constant.URI) + tags := queryParams.Get(constant.Tags) + fulltext := queryParams.Get(constant.Fulltext) + + log.Println("query: ", queryParams) + orderBy := queryParams.Get(constant.OrderBy) + orderDesc, err := strconv.ParseBool(queryParams.Get(constant.OrderDesc)) if err != nil { orderDesc = false } - first, err := strconv.ParseInt(query.Get(constant.First), 10, 16) + first, err := strconv.ParseInt(queryParams.Get(constant.First), 10, 16) if err != nil { first = 0 } - json, err := repository.BookmarkJSON(currentUserID, id, tags, fulltext, orderBy, orderDesc, int(first)) + json, err := repository.BookmarkJSON(currentUser, id, uri, tags, fulltext, orderBy, orderDesc, int(first)) if err != nil { if utils.Is404(err) { // on a rien retrouve, on renvoie une collection vide @@ -49,10 +50,10 @@ func getBookmarks(w http.ResponseWriter, r *http.Request) { } func getBookmark(w http.ResponseWriter, r *http.Request) { - currentUserID := r.Context().Value(constant.User).(model.BowUser) + currentUser := r.Context().Value(constant.User).(model.BowUser) id := mux.Vars(r)["id"] - json, err := repository.BookmarkJSON(currentUserID, id, "", "", "", false, 0) + json, err := repository.BookmarkJSON(currentUser, id, "", "", "", "", false, 0) if err != nil { utils.Throw(w, err) return @@ -66,7 +67,7 @@ func getBookmark(w http.ResponseWriter, r *http.Request) { } func getTags(w http.ResponseWriter, r *http.Request) { - currentUserID := r.Context().Value(constant.User).(model.BowUser) + currentUser := r.Context().Value(constant.User).(model.BowUser) query := r.URL.Query() filter := query.Get(constant.Filter) @@ -75,7 +76,7 @@ func getTags(w http.ResponseWriter, r *http.Request) { withCount = false } - json, err := repository.TagsJSON(currentUserID, filter, withCount) + json, err := repository.TagsJSON(currentUser, filter, withCount) if err != nil { utils.Throw(w, err) return @@ -86,10 +87,10 @@ func getTags(w http.ResponseWriter, r *http.Request) { } func addOneVisit(w http.ResponseWriter, r *http.Request) { - currentUserID := r.Context().Value(constant.User).(model.BowUser) + currentUser := r.Context().Value(constant.User).(model.BowUser) id := mux.Vars(r)["id"] - uri, err := repository.AddOneVisit(currentUserID, id) + uri, err := repository.AddOneVisit(currentUser, id) if err != nil { utils.Throw(w, err) return @@ -99,18 +100,18 @@ func addOneVisit(w http.ResponseWriter, r *http.Request) { } func addBookmark(w http.ResponseWriter, r *http.Request) { - currentUserID := r.Context().Value(constant.User).(model.BowUser) + currentUser := r.Context().Value(constant.User).(model.BowUser) var bookmark model.Bookmark err := json.NewDecoder(r.Body).Decode(&bookmark) if err != nil { - utils.Throw(w, utils.NewHTTPError400(err, currentUserID)) + utils.Throw(w, utils.NewHTTPError400(err, currentUser)) return } - id, err := repository.CreateBookmark(currentUserID, bookmark) + id, err := repository.CreateBookmark(currentUser, bookmark) if err != nil { - utils.Throw(w, utils.NewHTTPError500(err, currentUserID)) + utils.Throw(w, utils.NewHTTPError500(err, currentUser)) return } @@ -133,20 +134,20 @@ func deleteBookmark(w http.ResponseWriter, r *http.Request) { updateBookmark save bookmark withour AuthenticationInfo */ func updateBookmark(w http.ResponseWriter, r *http.Request) { - currentUserID := r.Context().Value(constant.User).(model.BowUser) + currentUser := r.Context().Value(constant.User).(model.BowUser) id := mux.Vars(r)["id"] var bookmark model.Bookmark err := json.NewDecoder(r.Body).Decode(&bookmark) if err != nil { - utils.Throw(w, utils.NewHTTPError400(err, currentUserID)) + utils.Throw(w, utils.NewHTTPError400(err, currentUser)) return } bookmark.ID = id - err = repository.UpdateBookmark(currentUserID, bookmark) + err = repository.UpdateBookmark(currentUser, bookmark) if err != nil { - utils.Throw(w, utils.NewHTTPError500(err, currentUserID)) + utils.Throw(w, utils.NewHTTPError500(err, currentUser)) return } } diff --git a/pkg/http/router.go b/pkg/http/router.go index 8eb71c4..da1f5f7 100644 --- a/pkg/http/router.go +++ b/pkg/http/router.go @@ -54,7 +54,7 @@ func Start(addr string) { s.HandleFunc("/bookmarks/{id}", updateBookmark).Methods(http.MethodPut, http.MethodOptions) s.HandleFunc("/bookmarks/{id}/visit", addOneVisit).Methods(http.MethodGet, http.MethodPost, http.MethodOptions) s.HandleFunc("/bookmarks/{id}/authenticationinfo", updateBookmarkAuthenticationInfo).Methods(http.MethodPut, http.MethodOptions) - s.HandleFunc("/actions", doActions).Methods(http.MethodGet, http.MethodPost, http.MethodOptions) + s.HandleFunc("/action", doActions).Methods(http.MethodGet, http.MethodPost, http.MethodOptions) srv := &http.Server{ Handler: router, @@ -156,7 +156,7 @@ func authentication(next http.Handler) http.Handler { // try as application token user, err = repository.UserFromToken(token, "id", "login", "creationdate", "maxtagincloud", "maxresult", "actions") if err != nil { - utils.Throw(w, err) + utils.Throw(w, utils.NewHTTPError500(err, constant.Nobody)) return } } else if err != nil { diff --git a/pkg/repository/bookmarkRepository.go b/pkg/repository/bookmarkRepository.go index 1ea4e0a..6afaef2 100644 --- a/pkg/repository/bookmarkRepository.go +++ b/pkg/repository/bookmarkRepository.go @@ -16,7 +16,7 @@ import ( /* BookmarkJSON retourne le bookmark au format json */ -func BookmarkJSON(currentUser model.BowUser, id string, tags string, fulltext string, orderBy string, orderDesc bool, first int) (string, error) { +func BookmarkJSON(currentUser model.BowUser, id string, uri string, tags string, fulltext string, orderBy string, orderDesc bool, first int) (string, error) { var result string var err error @@ -36,10 +36,13 @@ func BookmarkJSON(currentUser model.BowUser, id string, tags string, fulltext st orderDirection = "desc" } - log.Printf("search bookmark id: %v, tags: '%v', fulltext: '%v', orderBy: %v, orderDesc: %v, first:%v", id, tags, fulltext, orderBy, orderDesc, first) + log.Printf("search bookmark id: %v, uri: %v, tags: '%v', fulltext: '%v', orderBy: %v, orderDesc: %v, first:%v", id, uri, tags, fulltext, orderBy, orderDesc, first) if id != "" { q := &query{sql: `WITH __all AS (select * from bookmark where id=$1) SELECT json_agg(__all.*) as j FROM __all`} result, err = q.QueryString(currentUser, id) + } else if uri != "" { + q := &query{sql: `WITH __all AS (select * from bookmark where uri=$1) SELECT json_agg(__all.*) as j FROM __all`} + result, err = q.QueryString(currentUser, uri) } else { tagsJSON := "{" + strings.Join(strings.Fields(tags), ",") + "}" q := &query{sql: fmt.Sprintf(` @@ -65,7 +68,7 @@ func TagsJSON(currentUser model.BowUser, filter string, withCount bool) (string, } else { q = &query{sql: `WITH __all AS (select distinct unnest(tags) as tag from bookmark order by 1), __some AS (select * from __all where tag ilike $1) select json_agg(tag) from __some;`} } - substring := fmt.Sprintf("%%%s%%", filter) + substring := fmt.Sprintf("%%%s%%", filter) // to do like, with must have many % :) result, err := q.QueryString(currentUser, substring) if err != nil { return "", utils.NewHTTPError500(err, currentUser) diff --git a/pkg/repository/database.go b/pkg/repository/database.go index 8f1e3e7..092f846 100644 --- a/pkg/repository/database.go +++ b/pkg/repository/database.go @@ -269,7 +269,7 @@ func (q *query) QueryString(currentUser model.BowUser, arguments ...interface{}) var pgjson pgtype.JSON err = row.Scan(&pgjson) if err != nil { - return "", utils.NewHTTPError500(err, currentUser) + return "", utils.NewHTTPError(fmt.Sprintf("Can't execute query '%s' %s (%v)", utils.RemoveTagReturn(q.sql), argToString(arguments...), err), currentUser, 500) } if q.postsql != "" { @@ -296,3 +296,15 @@ func (q *query) QueryString(currentUser model.BowUser, arguments ...interface{}) return result, nil } + +func argToString(arguments ...interface{}) string { + result := "" + if len(arguments) > 0 { + var argstring = make([]string, len(arguments)) + for i, arg := range arguments { + argstring[i] = fmt.Sprintf("'%v'", arg) + } + result = "with arguments: " + strings.Join(argstring, ", ") + } + return result +} \ No newline at end of file diff --git a/pkg/repository/userRepository.go b/pkg/repository/userRepository.go index 6dd0b21..fb6a7ec 100644 --- a/pkg/repository/userRepository.go +++ b/pkg/repository/userRepository.go @@ -60,9 +60,11 @@ func UserFromToken(token string, fields ...string) (model.BowUser, error) { tokenJSON := fmt.Sprintf(`{"token": "%s"}`, token) q := &query{sql: fmt.Sprintf(` - select $1 from bowuser b + WITH __all AS (select %s from bowuser b where exists (select * from jsonb_array_elements(tokens) as x - where x @> $1);`, allFields)} + where x @> $1)) + SELECT json_agg(__all) as j + FROM __all;`, allFields)} result, err := q.QueryString(currentUser, tokenJSON) if err != nil { return user, utils.NewHTTPError500(err, currentUser) diff --git a/pkg/utils/error.go b/pkg/utils/error.go index 99be5d6..ddaea58 100644 --- a/pkg/utils/error.go +++ b/pkg/utils/error.go @@ -10,6 +10,12 @@ import ( "gitlab.chorem.org/chorem/bow/pkg/model" ) +type codeRef struct { + file string + fn string + line int +} + /* httpError erreur permettant de porter le code HTTP souhaite */ @@ -18,15 +24,21 @@ type httpError struct { Msg string CurrentUserID string StatusCode int - file string - fn string - line int + stack []codeRef } func (e *httpError) Error() string { return fmt.Sprintf(`{"ID": "%s", "currentUser": "%s", "StatusCode": %v, "Msg": %q}`, e.ID, e.CurrentUserID, e.StatusCode, e.Msg) } +func addCodeRef(err *httpError) { + pc, file, line, _ := runtime.Caller(3) + fn := runtime.FuncForPC(pc).Name() + pos := strings.LastIndex(fn, "/") + pos = strings.Index(fn[pos:], ".") + pos + 1 + err.stack = append(err.stack, codeRef{file: file, fn:fn[pos:], line: line}) +} + func createHTTPError(msg string, currentUser model.BowUser, statusCode int) *httpError { e := httpError{} e.ID, _ = GenUUID() @@ -37,15 +49,8 @@ func createHTTPError(msg string, currentUser model.BowUser, statusCode int) *htt } else { e.StatusCode = 500 } - - pc, file, line, _ := runtime.Caller(2) - fn := runtime.FuncForPC(pc).Name() - pos := strings.LastIndex(fn, "/") - pos = strings.Index(fn[pos:], ".") + pos + 1 - e.file = file - e.fn = fn[pos:] - e.line = line - + e.stack = make([]codeRef, 0, 1) + addCodeRef(&e) return &e } @@ -55,6 +60,7 @@ func NewHTTPError(msg string, currentUser model.BowUser, statusCode int) *httpEr func NewHTTPError400(err error, currentUser model.BowUser) *httpError { if err, ok := err.(*httpError); ok { + addCodeRef(err) return err } @@ -63,6 +69,7 @@ func NewHTTPError400(err error, currentUser model.BowUser) *httpError { func NewHTTPError500(err error, currentUser model.BowUser) *httpError { if err, ok := err.(*httpError); ok { + addCodeRef(err) return err } @@ -79,7 +86,10 @@ func Is404(err error) bool { func Throw(w http.ResponseWriter, err error) { if err, ok := err.(*httpError); ok { if err.StatusCode >= 500 || true { // FIXME faire mode debug - log.Printf("[error] in [%s#%s:%d] %v", err.file, err.fn, err.line, err) + log.Printf("[error] %v\n", err) + for _, ref := range err.stack { + log.Printf("\tin [%s#%s:%d] ", ref.file, ref.fn, ref.line) + } } http.Error(w, fmt.Sprintf("%s", err), err.StatusCode) } else { diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go new file mode 100644 index 0000000..d7dad83 --- /dev/null +++ b/pkg/utils/utils.go @@ -0,0 +1,17 @@ +package utils + +import ( + "strings" +) + +/* +RemoveTagReturn remove all \n and \t in the string +*/ +func RemoveTagReturn(s string) string { + return strings.Map(func(c rune) rune { + if c == '\n' || c == '\t' { + return -1 + } + return c + }, s) +} diff --git a/web/public/index.html b/web/public/index.html index c053282..4703ad2 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -5,6 +5,7 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.png"> + <link title="bow" type="application/opensearchdescription+xml" rel="search" href="/opensearch.xml"> <title>Bow - <%= htmlWebpackPlugin.options.title %></title> </head> <body> diff --git a/web/public/opensearch.xml b/web/public/opensearch.xml new file mode 100644 index 0000000..d51563f --- /dev/null +++ b/web/public/opensearch.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/"> + <ShortName>Bow</ShortName> + <Description>Search with Bow</Description> + <InputEncoding>UTF-8</InputEncoding> + <LongName>Bow Search</LongName> + <Image height="16" width="16">data:image/x-icon;base64,R0lGODlhEAAQAMMCAAAAAP97AP////+9hP/nxv+cQsbGxoSEhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAUAAAgALAAAAAAQABAAAARHEIE5kbWUhr0rFmA2ccAFhJIJdNJwlqnZEaUXYwB97Xe+wryUbxUA8nwY1lEnM7ZqsiKuAKxKTwYn7Ic9OIXFiTeIu353lQgAOw==</Image> + <Url type="text/html" method="get" template="https://localhost:8000/api/v1/action?action={searchTerms}"/> + <Url type="application/x-suggestions+json" template="https://localhost:8000/api/v1/action?suggestion={searchTerms}"/> + <moz:SearchForm>https://bow.chorem.org/bow/</moz:SearchForm> +</OpenSearchDescription> diff --git a/web/src/components/SearchInput.vue b/web/src/components/SearchInput.vue index ebabd94..487e01b 100644 --- a/web/src/components/SearchInput.vue +++ b/web/src/components/SearchInput.vue @@ -61,9 +61,9 @@ class SearchInput extends Vue { !this.sameValue(this.mFulltext, this.first) ) { let query = {} - this.mTags && (query.t = this.mTags) - this.mFulltext && (query.f = this.mFulltext) - this.mQuery && (query.q = this.mQuery) + this.mTags && (query.tags = this.mTags) + this.mFulltext && (query.fulltext = this.mFulltext) + this.mQuery && (query.query = this.mQuery) this.mOrderby && (query.orderBy = this.mOrderby) this.mOrderdesc && (query.orderDesc = this.mOrderdesc) this.mFulltext && (query.first = this.mFirst) diff --git a/web/src/views/BookmarkEdit.vue b/web/src/views/BookmarkEdit.vue index d94ecd4..cfdca4e 100644 --- a/web/src/views/BookmarkEdit.vue +++ b/web/src/views/BookmarkEdit.vue @@ -48,9 +48,9 @@ class BookmarkEdit extends Vue { bookmark = { uri: this.uri, description: this.description, - tags: this.tags, - privatealias: this.privatealias, - publicalias: this.publicalias, + tags: this.stringToArray(this.tags), + privatealias: this.stringToArray(this.privatealias), + publicalias: this.stringToArray(this.publicalias), lang: this.lang } @@ -64,6 +64,25 @@ class BookmarkEdit extends Vue { this.errorMsg = err.cause } ) + } else if (this.bookmark.uri) { + let searchParams = new URLSearchParams() + this.uri && searchParams.append('uri', this.bookmark.uri) + this.$fetch.get(`/bookmarks?${searchParams.toString()}`).then( + data => { + if (data.length > 0) { + let b = data[0] + this.bookmark.id = b.id + this.bookmark.description = b.description + '\n' + new Date().toISOString().slice(0, 10) + '\n' + this.bookmark.description + this.bookmark.tags = [...new Set(this.stringToArray(b.tags).concat(this.bookmark.tags))] + this.bookmark.privatealias = [...new Set(this.stringToArray(b.privatealias).concat(this.bookmark.privatealias))] + this.bookmark.publicalias = [...new Set(this.stringToArray(b.publicalias).concat(this.bookmark.publicalias))] + this.bookmark.lang = b.lang || this.bookmark.lang + } + }, + err => { + this.errorMsg = err.cause + } + ) } } @@ -71,15 +90,33 @@ class BookmarkEdit extends Vue { this.$router.go(-1) } + stringToArray(s) { + if (!s) { + return [] + } + + if (!Array.isArray(s)) { + return s.split(/[,\s*]/) + } + + return s + } + save() { let promise - if (this.bookmark.tags && !Array.isArray(this.bookmark.tags)) { + if (!this.bookmark.tags) { + this.bookmark.tags = [] + } else if (!Array.isArray(this.bookmark.tags)) { this.bookmark.tags = this.bookmark.tags.split(/[,\s*]/) } - if (this.bookmark.privatealias && !Array.isArray(this.bookmark.privatealias)) { + if (!this.bookmark.privatealias) { + this.bookmark.privatealias = [] + } else if (!Array.isArray(this.bookmark.privatealias)) { this.bookmark.privatealias = this.bookmark.privatealias.split(/[,\s*]/) } - if (this.bookmark.publicalias && !Array.isArray(this.bookmark.publicalias)) { + if (!this.bookmark.publicalias) { + this.bookmark.publicalias = [] + } else if (!Array.isArray(this.bookmark.publicalias)) { this.bookmark.publicalias = this.bookmark.publicalias.split(/[,\s*]/) } -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm