mirror of
https://github.com/nkanaev/yarr.git
synced 2025-05-24 21:19:19 +00:00
switch to the standard logger
This commit is contained in:
parent
3539433a9d
commit
cc7bdc5b76
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
- fix: scrollTo/scrollBy with smooth behavior instead of scrollTop
|
- fix: scrollTo/scrollBy with smooth behavior instead of scrollTop
|
||||||
|
|
||||||
- ref: switch to the standard logger
|
|
||||||
- ref: organize "server" package using KonMari method
|
- ref: organize "server" package using KonMari method
|
||||||
https://github.com/gin-gonic/gin : nice example of router api
|
https://github.com/gin-gonic/gin : nice example of router api
|
||||||
|
|
||||||
|
25
src/main.go
25
src/main.go
@ -18,6 +18,9 @@ var Version string = "0.0"
|
|||||||
var GitHash string = "unknown"
|
var GitHash string = "unknown"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
log.SetOutput(os.Stdout)
|
||||||
|
log.SetFlags(log.Ldate|log.Ltime|log.Lshortfile)
|
||||||
|
|
||||||
var addr, db, authfile, certfile, keyfile string
|
var addr, db, authfile, certfile, keyfile string
|
||||||
var ver, open bool
|
var ver, open bool
|
||||||
flag.StringVar(&addr, "addr", "127.0.0.1:7070", "address to run server on")
|
flag.StringVar(&addr, "addr", "127.0.0.1:7070", "address to run server on")
|
||||||
@ -43,28 +46,26 @@ func main() {
|
|||||||
server.BasePath = strings.TrimSuffix(server.BasePath, "/")
|
server.BasePath = strings.TrimSuffix(server.BasePath, "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
logger := log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
|
|
||||||
|
|
||||||
configPath, err := os.UserConfigDir()
|
configPath, err := os.UserConfigDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("Failed to get config dir: ", err)
|
log.Fatal("Failed to get config dir: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if db == "" {
|
if db == "" {
|
||||||
storagePath := filepath.Join(configPath, "yarr")
|
storagePath := filepath.Join(configPath, "yarr")
|
||||||
if err := os.MkdirAll(storagePath, 0755); err != nil {
|
if err := os.MkdirAll(storagePath, 0755); err != nil {
|
||||||
logger.Fatal("Failed to create app config dir: ", err)
|
log.Fatal("Failed to create app config dir: ", err)
|
||||||
}
|
}
|
||||||
db = filepath.Join(storagePath, "storage.db")
|
db = filepath.Join(storagePath, "storage.db")
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Printf("using db file %s", db)
|
log.Printf("using db file %s", db)
|
||||||
|
|
||||||
var username, password string
|
var username, password string
|
||||||
if authfile != "" {
|
if authfile != "" {
|
||||||
f, err := os.Open(authfile)
|
f, err := os.Open(authfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("Failed to open auth file: ", err)
|
log.Fatal("Failed to open auth file: ", err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
scanner := bufio.NewScanner(f)
|
scanner := bufio.NewScanner(f)
|
||||||
@ -72,7 +73,7 @@ func main() {
|
|||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
parts := strings.Split(line, ":")
|
parts := strings.Split(line, ":")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
logger.Fatalf("Invalid auth: %v (expected `username:password`)", line)
|
log.Fatalf("Invalid auth: %v (expected `username:password`)", line)
|
||||||
}
|
}
|
||||||
username = parts[0]
|
username = parts[0]
|
||||||
password = parts[1]
|
password = parts[1]
|
||||||
@ -81,15 +82,15 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (certfile != "" || keyfile != "") && (certfile == "" || keyfile == "") {
|
if (certfile != "" || keyfile != "") && (certfile == "" || keyfile == "") {
|
||||||
logger.Fatalf("Both cert & key files are required")
|
log.Fatalf("Both cert & key files are required")
|
||||||
}
|
}
|
||||||
|
|
||||||
store, err := storage.New(db, logger)
|
store, err := storage.New(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatal("Failed to initialise database: ", err)
|
log.Fatal("Failed to initialise database: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
srv := server.New(store, logger, addr)
|
srv := server.New(store, addr)
|
||||||
|
|
||||||
if certfile != "" && keyfile != "" {
|
if certfile != "" && keyfile != "" {
|
||||||
srv.CertFile = certfile
|
srv.CertFile = certfile
|
||||||
@ -101,7 +102,7 @@ func main() {
|
|||||||
srv.Password = password
|
srv.Password = password
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Printf("starting server at %s", srv.GetAddr())
|
log.Printf("starting server at %s", srv.GetAddr())
|
||||||
if open {
|
if open {
|
||||||
platform.Open(srv.GetAddr())
|
platform.Open(srv.GetAddr())
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"github.com/nkanaev/yarr/src/assets"
|
"github.com/nkanaev/yarr/src/assets"
|
||||||
"html"
|
"html"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -94,7 +95,7 @@ func FolderListHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
} else if req.Method == "POST" {
|
} else if req.Method == "POST" {
|
||||||
var body FolderCreateForm
|
var body FolderCreateForm
|
||||||
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -120,7 +121,7 @@ func FolderHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
if req.Method == "PUT" {
|
if req.Method == "PUT" {
|
||||||
var body FolderUpdateForm
|
var body FolderUpdateForm
|
||||||
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -174,14 +175,14 @@ func FeedListHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
} else if req.Method == "POST" {
|
} else if req.Method == "POST" {
|
||||||
var form FeedCreateForm
|
var form FeedCreateForm
|
||||||
if err := json.NewDecoder(req.Body).Decode(&form); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&form); err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
feed, sources, err := discoverFeed(form.Url)
|
feed, sources, err := discoverFeed(form.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
writeJSON(rw, map[string]string{"status": "notfound"})
|
writeJSON(rw, map[string]string{"status": "notfound"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -201,7 +202,7 @@ func FeedListHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
db(req).UpdateFeedIcon(storedFeed.Id, icon)
|
db(req).UpdateFeedIcon(storedFeed.Id, icon)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler(req).log.Printf("Failed to find favicon for %s (%d): %s", storedFeed.FeedLink, storedFeed.Id, err)
|
log.Printf("Failed to find favicon for %s (%d): %s", storedFeed.FeedLink, storedFeed.Id, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
writeJSON(rw, map[string]string{"status": "success"})
|
writeJSON(rw, map[string]string{"status": "success"})
|
||||||
@ -227,7 +228,7 @@ func FeedHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
body := make(map[string]interface{})
|
body := make(map[string]interface{})
|
||||||
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -262,7 +263,7 @@ func ItemHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
var body ItemUpdateForm
|
var body ItemUpdateForm
|
||||||
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&body); err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
rw.WriteHeader(http.StatusBadRequest)
|
rw.WriteHeader(http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -347,12 +348,12 @@ func OPMLImportHandler(rw http.ResponseWriter, req *http.Request) {
|
|||||||
if req.Method == "POST" {
|
if req.Method == "POST" {
|
||||||
file, _, err := req.FormFile("opml")
|
file, _, err := req.FormFile("opml")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
doc, err := parseOPML(file)
|
doc, err := parseOPML(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handler(req).log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, outline := range doc.Outlines {
|
for _, outline := range doc.Outlines {
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
type Handler struct {
|
type Handler struct {
|
||||||
Addr string
|
Addr string
|
||||||
db *storage.Storage
|
db *storage.Storage
|
||||||
log *log.Logger
|
|
||||||
feedQueue chan storage.Feed
|
feedQueue chan storage.Feed
|
||||||
queueSize *int32
|
queueSize *int32
|
||||||
refreshRate chan int64
|
refreshRate chan int64
|
||||||
@ -27,11 +26,10 @@ type Handler struct {
|
|||||||
KeyFile string
|
KeyFile string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(db *storage.Storage, logger *log.Logger, addr string) *Handler {
|
func New(db *storage.Storage, addr string) *Handler {
|
||||||
queueSize := int32(0)
|
queueSize := int32(0)
|
||||||
return &Handler{
|
return &Handler{
|
||||||
db: db,
|
db: db,
|
||||||
log: logger,
|
|
||||||
feedQueue: make(chan storage.Feed, 3000),
|
feedQueue: make(chan storage.Feed, 3000),
|
||||||
queueSize: &queueSize,
|
queueSize: &queueSize,
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
@ -58,7 +56,7 @@ func (h *Handler) Start() {
|
|||||||
err = s.ListenAndServe()
|
err = s.ListenAndServe()
|
||||||
}
|
}
|
||||||
if err != http.ErrServerClosed {
|
if err != http.ErrServerClosed {
|
||||||
h.log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +122,7 @@ func (h *Handler) startJobs() {
|
|||||||
items, err := listItems(feed, h.db)
|
items, err := listItems(feed, h.db)
|
||||||
atomic.AddInt32(h.queueSize, -1)
|
atomic.AddInt32(h.queueSize, -1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log.Printf("Failed to fetch %s (%d): %s", feed.FeedLink, feed.Id, err)
|
log.Printf("Failed to fetch %s (%d): %s", feed.FeedLink, feed.Id, err)
|
||||||
h.db.SetFeedError(feed.Id, err)
|
h.db.SetFeedError(feed.Id, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -136,7 +134,7 @@ func (h *Handler) startJobs() {
|
|||||||
h.db.UpdateFeedIcon(feed.Id, icon)
|
h.db.UpdateFeedIcon(feed.Id, icon)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.log.Printf("Failed to search favicon for %s (%s): %s", feed.Link, feed.FeedLink, err)
|
log.Printf("Failed to search favicon for %s (%s): %s", feed.Link, feed.FeedLink, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-delTicker.C:
|
case <-delTicker.C:
|
||||||
@ -190,7 +188,7 @@ func (h Handler) requiresAuth() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) fetchAllFeeds() {
|
func (h *Handler) fetchAllFeeds() {
|
||||||
h.log.Print("Refreshing all feeds")
|
log.Print("Refreshing all feeds")
|
||||||
h.db.ResetFeedErrors()
|
h.db.ResetFeedErrors()
|
||||||
for _, feed := range h.db.ListFeeds() {
|
for _, feed := range h.db.ListFeeds() {
|
||||||
h.fetchFeed(feed)
|
h.fetchFeed(feed)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"html"
|
"html"
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
@ -60,7 +61,7 @@ func (s *Storage) CreateFeed(title, description, link, feedLink string, folderId
|
|||||||
func (s *Storage) DeleteFeed(feedId int64) bool {
|
func (s *Storage) DeleteFeed(feedId int64) bool {
|
||||||
_, err := s.db.Exec(`delete from feeds where id = ?`, feedId)
|
_, err := s.db.Exec(`delete from feeds where id = ?`, feedId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
@ -89,7 +90,7 @@ func (s *Storage) ListFeeds() []Feed {
|
|||||||
order by title collate nocase
|
order by title collate nocase
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@ -104,7 +105,7 @@ func (s *Storage) ListFeeds() []Feed {
|
|||||||
&f.HasIcon,
|
&f.HasIcon,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
result = append(result, f)
|
result = append(result, f)
|
||||||
@ -137,7 +138,7 @@ func (s *Storage) GetFeed(id int64) *Feed {
|
|||||||
|
|
||||||
func (s *Storage) ResetFeedErrors() {
|
func (s *Storage) ResetFeedErrors() {
|
||||||
if _, err := s.db.Exec(`delete from feed_errors`); err != nil {
|
if _, err := s.db.Exec(`delete from feed_errors`); err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +150,7 @@ func (s *Storage) SetFeedError(feedID int64, lastError error) {
|
|||||||
feedID, lastError.Error(),
|
feedID, lastError.Error(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +159,7 @@ func (s *Storage) GetFeedErrors() map[int64]string {
|
|||||||
|
|
||||||
rows, err := s.db.Query(`select feed_id, error from feed_errors`)
|
rows, err := s.db.Query(`select feed_id, error from feed_errors`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +167,7 @@ func (s *Storage) GetFeedErrors() map[int64]string {
|
|||||||
var id int64
|
var id int64
|
||||||
var error string
|
var error string
|
||||||
if err = rows.Scan(&id, &error); err != nil {
|
if err = rows.Scan(&id, &error); err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
errors[id] = error
|
errors[id] = error
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Folder struct {
|
type Folder struct {
|
||||||
@ -25,19 +26,19 @@ func (s *Storage) CreateFolder(title string) *Folder {
|
|||||||
var id int64
|
var id int64
|
||||||
numrows, err := result.RowsAffected()
|
numrows, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if numrows == 1 {
|
if numrows == 1 {
|
||||||
id, err = result.LastInsertId()
|
id, err = result.LastInsertId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = s.db.QueryRow(`select id, is_expanded from folders where title=?`, title).Scan(&id, &expanded)
|
err = s.db.QueryRow(`select id, is_expanded from folders where title=?`, title).Scan(&id, &expanded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,7 +48,7 @@ func (s *Storage) CreateFolder(title string) *Folder {
|
|||||||
func (s *Storage) DeleteFolder(folderId int64) bool {
|
func (s *Storage) DeleteFolder(folderId int64) bool {
|
||||||
_, err := s.db.Exec(`delete from folders where id = ?`, folderId)
|
_, err := s.db.Exec(`delete from folders where id = ?`, folderId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
@ -70,14 +71,14 @@ func (s *Storage) ListFolders() []Folder {
|
|||||||
order by title collate nocase
|
order by title collate nocase
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var f Folder
|
var f Folder
|
||||||
err = rows.Scan(&f.Id, &f.Title, &f.IsExpanded)
|
err = rows.Scan(&f.Id, &f.Title, &f.IsExpanded)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
result = append(result, f)
|
result = append(result, f)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ func (s *Storage) ListHTTPStates() map[int64]HTTPState {
|
|||||||
result := make(map[int64]HTTPState)
|
result := make(map[int64]HTTPState)
|
||||||
rows, err := s.db.Query(`select feed_id, last_refreshed, last_modified, etag from http_states`)
|
rows, err := s.db.Query(`select feed_id, last_refreshed, last_modified, etag from http_states`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@ -28,7 +29,7 @@ func (s *Storage) ListHTTPStates() map[int64]HTTPState {
|
|||||||
&state.Etag,
|
&state.Etag,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
result[state.FeedID] = state
|
result[state.FeedID] = state
|
||||||
@ -67,6 +68,6 @@ func (s *Storage) SetHTTPState(feedID int64, lastModified, etag string) {
|
|||||||
lastModified, etag,
|
lastModified, etag,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
xhtml "golang.org/x/net/html"
|
xhtml "golang.org/x/net/html"
|
||||||
@ -73,7 +74,7 @@ type MarkFilter struct {
|
|||||||
func (s *Storage) CreateItems(items []Item) bool {
|
func (s *Storage) CreateItems(items []Item) bool {
|
||||||
tx, err := s.db.Begin()
|
tx, err := s.db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -105,16 +106,16 @@ func (s *Storage) CreateItems(items []Item) bool {
|
|||||||
item.DateUpdated, now,
|
item.DateUpdated, now,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
if err = tx.Rollback(); err != nil {
|
if err = tx.Rollback(); err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = tx.Commit(); err != nil {
|
if err = tx.Commit(); err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -175,7 +176,7 @@ func (s *Storage) ListItems(filter ItemFilter, offset, limit int, newestFirst bo
|
|||||||
`, predicate, order, limit, offset)
|
`, predicate, order, limit, offset)
|
||||||
rows, err := s.db.Query(query, args...)
|
rows, err := s.db.Query(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@ -196,7 +197,7 @@ func (s *Storage) ListItems(filter ItemFilter, offset, limit int, newestFirst bo
|
|||||||
&x.PodcastURL,
|
&x.PodcastURL,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
result = append(result, x)
|
result = append(result, x)
|
||||||
@ -251,7 +252,7 @@ func (s *Storage) MarkItemsRead(filter MarkFilter) bool {
|
|||||||
`, READ, predicate, STARRED)
|
`, READ, predicate, STARRED)
|
||||||
_, err := s.db.Exec(query, args...)
|
_, err := s.db.Exec(query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
@ -273,7 +274,7 @@ func (s *Storage) FeedStats() []FeedStat {
|
|||||||
group by feed_id
|
group by feed_id
|
||||||
`, UNREAD, STARRED))
|
`, UNREAD, STARRED))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@ -310,7 +311,7 @@ func (s *Storage) SyncSearch() {
|
|||||||
where search_rowid is null;
|
where search_rowid is null;
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +328,7 @@ func (s *Storage) SyncSearch() {
|
|||||||
item.Title, HTMLText(item.Description), HTMLText(item.Content),
|
item.Title, HTMLText(item.Description), HTMLText(item.Content),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if numrows, err := result.RowsAffected(); err == nil && numrows == 1 {
|
if numrows, err := result.RowsAffected(); err == nil && numrows == 1 {
|
||||||
@ -351,7 +352,7 @@ func (s *Storage) DeleteOldItems() {
|
|||||||
`, STARRED))
|
`, STARRED))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,16 +371,16 @@ func (s *Storage) DeleteOldItems() {
|
|||||||
time.Now().Add(-time.Hour*24*90), // 90 days
|
time.Now().Add(-time.Hour*24*90), // 90 days
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
num, err := result.RowsAffected()
|
num, err := result.RowsAffected()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if num > 0 {
|
if num > 0 {
|
||||||
s.log.Printf("Deleted %d old items (%d)", num, feedId)
|
log.Printf("Deleted %d old items (%d)", num, feedId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ var migrations = []func(*sql.Tx)error{
|
|||||||
|
|
||||||
var maxVersion = int64(len(migrations))
|
var maxVersion = int64(len(migrations))
|
||||||
|
|
||||||
func migrate(db *sql.DB, log *log.Logger) error {
|
func migrate(db *sql.DB) error {
|
||||||
var version int64
|
var version int64
|
||||||
db.QueryRow("pragma user_version").Scan(&version);
|
db.QueryRow("pragma user_version").Scan(&version);
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import "encoding/json"
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
func settingsDefaults() map[string]interface{} {
|
func settingsDefaults() map[string]interface{} {
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
@ -28,7 +31,7 @@ func (s *Storage) GetSettingsValue(key string) interface{} {
|
|||||||
}
|
}
|
||||||
var valDecoded interface{}
|
var valDecoded interface{}
|
||||||
if err := json.Unmarshal([]byte(val), &valDecoded); err != nil {
|
if err := json.Unmarshal([]byte(val), &valDecoded); err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return valDecoded
|
return valDecoded
|
||||||
@ -48,7 +51,7 @@ func (s *Storage) GetSettings() map[string]interface{} {
|
|||||||
result := settingsDefaults()
|
result := settingsDefaults()
|
||||||
rows, err := s.db.Query(`select key, val from settings;`)
|
rows, err := s.db.Query(`select key, val from settings;`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@ -58,7 +61,7 @@ func (s *Storage) GetSettings() map[string]interface{} {
|
|||||||
|
|
||||||
rows.Scan(&key, &val)
|
rows.Scan(&key, &val)
|
||||||
if err = json.Unmarshal([]byte(val), &valDecoded); err != nil {
|
if err = json.Unmarshal([]byte(val), &valDecoded); err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
result[key] = valDecoded
|
result[key] = valDecoded
|
||||||
@ -74,7 +77,7 @@ func (s *Storage) UpdateSettings(kv map[string]interface{}) bool {
|
|||||||
}
|
}
|
||||||
valEncoded, err := json.Marshal(val)
|
valEncoded, err := json.Marshal(val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
_, err = s.db.Exec(`
|
_, err = s.db.Exec(`
|
||||||
@ -83,7 +86,7 @@ func (s *Storage) UpdateSettings(kv map[string]interface{}) bool {
|
|||||||
key, valEncoded, valEncoded,
|
key, valEncoded, valEncoded,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Print(err)
|
log.Print(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,15 +3,13 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
log *log.Logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(path string, log *log.Logger) (*Storage, error) {
|
func New(path string) (*Storage, error) {
|
||||||
db, err := sql.Open("sqlite3", path)
|
db, err := sql.Open("sqlite3", path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -19,8 +17,8 @@ func New(path string, log *log.Logger) (*Storage, error) {
|
|||||||
|
|
||||||
db.SetMaxOpenConns(1)
|
db.SetMaxOpenConns(1)
|
||||||
|
|
||||||
if err = migrate(db, log); err != nil {
|
if err = migrate(db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Storage{db: db, log: log}, nil
|
return &Storage{db: db}, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user