remove fever code

This commit is contained in:
Nazar Kanaev 2020-12-16 00:02:45 +00:00
parent 62e0caa950
commit db7a178a8d
3 changed files with 0 additions and 343 deletions

View File

@ -1,313 +0,0 @@
package server
import (
"encoding/base64"
"fmt"
"github.com/nkanaev/yarr/storage"
"net/http"
"strconv"
"strings"
"time"
)
var feverHandlers = map[string]func(rw http.ResponseWriter, req *http.Request){
"groups": FeverGroupsHandler,
"feeds": FeverFeedsHandler,
"unread_item_ids": FeverFilteredItemIDsHandler,
"saved_item_ids": FeverFilteredItemIDsHandler,
"favicons": FeverFaviconsHandler,
"items": FeverItemsHandler,
"links": FeverLinksHandler,
"mark": FeverMarkHandler,
}
type FeverGroup struct {
ID int64 `json:"id"`
Title string `json:"title"`
}
type FeverFeedsGroup struct {
GroupID int64 `json:"group_id"`
FeedIDs string `json:"feed_ids"`
}
type FeverFeed struct {
ID int64 `json:"id"`
FaviconID int64 `json:"favicon_id"`
Title string `json:"title"`
Url string `json:"url"`
SiteUrl string `json:"site_url"`
IsSpark int `json:"is_spark"`
LastUpdated int64 `json:"last_updated_on_time"`
}
type FeverItem struct {
ID int64 `json:"id"`
FeedID int64 `json:"feed_id"`
Title string `json:"title"`
Author string `json:"author"`
HTML string `json:"html"`
Url string `json:"url"`
IsSaved int `json:"is_saved"`
IsRead int `json:"is_read"`
CreatedAt int64 `json:"created_on_time"`
}
type FeverFavicon struct {
ID int64 `json:"id"`
Data string `json:"data"`
}
func writeFeverJSON(rw http.ResponseWriter, data map[string]interface{}) {
data["api_version"] = 1
data["auth"] = 1
// NOTE: does not adhere to the API spec
data["last_refreshed_on_time"] = time.Now().Unix()
writeJSON(rw, data)
}
func FeverHandler(rw http.ResponseWriter, req *http.Request) {
query := req.URL.Query()
fmt.Println(req.URL.String())
for key, handler := range feverHandlers {
if _, ok := query[key]; ok {
handler(rw, req)
return
}
}
writeJSON(rw, map[string]interface{}{
"api_version": 1,
"auth": 1,
})
}
func joinInts(values []int64) string {
var result strings.Builder
for i, val := range values {
fmt.Fprintf(&result, "%d", val)
if i != len(values)-1 {
result.WriteString(",")
}
}
return result.String()
}
func feedGroups(db *storage.Storage) []*FeverFeedsGroup {
feeds := db.ListFeeds()
groupFeeds := make(map[int64][]int64)
for _, feed := range feeds {
// TODO: what about top-level feeds?
if feed.FolderId == nil {
continue
}
groupFeeds[*feed.FolderId] = append(groupFeeds[*feed.FolderId], feed.Id)
}
result := make([]*FeverFeedsGroup, 0)
for groupId, feedIds := range groupFeeds {
result = append(result, &FeverFeedsGroup{
GroupID: groupId,
FeedIDs: joinInts(feedIds),
})
}
return result
}
func FeverGroupsHandler(rw http.ResponseWriter, req *http.Request) {
folders := db(req).ListFolders()
groups := make([]*FeverGroup, len(folders))
for i, folder := range folders {
groups[i] = &FeverGroup{ID: folder.Id, Title: folder.Title}
}
writeFeverJSON(rw, map[string]interface{}{
"groups": groups,
"feeds_groups": feedGroups(db(req)),
})
}
func FeverFeedsHandler(rw http.ResponseWriter, req *http.Request) {
feeds := db(req).ListFeeds()
httpStates := db(req).ListHTTPStates()
feverFeeds := make([]*FeverFeed, len(feeds))
for i, feed := range feeds {
var lastUpdated int64
if state, ok := httpStates[feed.Id]; ok {
lastUpdated = state.LastRefreshed.Unix()
}
feverFeeds[i] = &FeverFeed{
ID: feed.Id,
FaviconID: feed.Id,
Title: feed.Title,
Url: feed.FeedLink,
SiteUrl: feed.Link,
IsSpark: 0,
LastUpdated: lastUpdated,
}
}
writeFeverJSON(rw, map[string]interface{}{
"feeds": feverFeeds,
"feeds_groups": feedGroups(db(req)),
})
}
func FeverFilteredItemIDsHandler(rw http.ResponseWriter, req *http.Request) {
var status storage.ItemStatus
var filter string
if _, ok := req.URL.Query()["unread_item_ids"]; ok {
status = storage.UNREAD
filter = "unread_item_ids"
} else {
status = storage.STARRED
filter = "saved_item_ids"
}
itemIds := make([]int64, 0, 4000)
batch := 1000
index := 0
for {
items := db(req).ListItems(storage.ItemFilter{Status: &status}, index*batch, batch, true)
if len(items) == 0 {
break
}
for _, item := range items {
itemIds = append(itemIds, item.Id)
}
index += 1
}
writeFeverJSON(rw, map[string]interface{}{
filter: joinInts(itemIds),
})
}
func FeverFaviconsHandler(rw http.ResponseWriter, req *http.Request) {
feeds := db(req).ListFeeds()
favicons := make([]*FeverFavicon, len(feeds))
for i, feed := range feeds {
data := "data:image/gif;base64,R0lGODlhAQABAAAAACw="
if feed.HasIcon {
icon := db(req).GetFeed(feed.Id).Icon
data = fmt.Sprintf(
"data:%s;base64,%s",
http.DetectContentType(*icon),
base64.StdEncoding.EncodeToString(*icon),
)
}
favicons[i] = &FeverFavicon{ID: feed.Id, Data: data}
}
writeFeverJSON(rw, map[string]interface{}{
"favicons": favicons,
})
}
func FeverItemsHandler(rw http.ResponseWriter, req *http.Request) {
filter := storage.ItemFilter{}
query := req.URL.Query()
switch {
case query.Get("with_ids") != "":
ids := make([]int64, 0)
for _, idstr := range strings.Split(query.Get("with_ids"), ",") {
if idnum, err := strconv.ParseInt(idstr, 10, 64); err == nil {
ids = append(ids, idnum)
}
}
filter.IDs = &ids
case query.Get("since_id") != "":
idstr := query.Get("since_id")
if idnum, err := strconv.ParseInt(idstr, 10, 64); err == nil {
filter.SinceID = &idnum
}
case query.Get("max_id") != "":
idstr := query.Get("max_id")
if idnum, err := strconv.ParseInt(idstr, 10, 64); err == nil {
filter.MaxID = &idnum
}
}
items := db(req).ListItems(filter, 0, 50, true)
feverItems := make([]FeverItem, len(items))
for i, item := range items {
date := item.Date
if date == nil {
date = item.DateUpdated
}
time := int64(0)
if date != nil {
time = date.Unix()
}
isSaved := 0
if item.Status == storage.STARRED {
isSaved = 1
}
isRead := 0
if item.Status == storage.READ {
isRead = 1
}
feverItems[i] = FeverItem{
ID: item.Id,
FeedID: item.FeedId,
Title: item.Title,
Author: item.Author,
HTML: item.Content,
Url: item.Link,
IsSaved: isSaved,
IsRead: isRead,
CreatedAt: time,
}
}
writeFeverJSON(rw, map[string]interface{}{
"items": feverItems,
})
}
func FeverLinksHandler(rw http.ResponseWriter, req *http.Request) {
writeFeverJSON(rw, map[string]interface{}{
"links": make([]interface{}, 0),
})
}
func FeverMarkHandler(rw http.ResponseWriter, req *http.Request) {
query := req.URL.Query()
id, err := strconv.ParseInt(query.Get("id"), 10, 64)
if err != nil {
handler(req).log.Print("invalid id:", err)
return
}
switch query.Get("mark") {
case "item":
var status storage.ItemStatus
switch query.Get("as") {
case "read":
status = storage.READ
case "unread":
status = storage.UNREAD
case "saved":
status = storage.STARRED
case "unsaved":
status = storage.READ
default:
rw.WriteHeader(http.StatusBadRequest)
return
}
db(req).UpdateItemStatus(id, status)
case "feed":
x, _ := strconv.ParseInt(query.Get("before"), 10, 64)
before := time.Unix(x, 0)
db(req).MarkItemsRead(storage.MarkFilter{FeedID: &id, Before: &before})
case "group":
x, _ := strconv.ParseInt(query.Get("before"), 10, 64)
before := time.Unix(x, 0)
db(req).MarkItemsRead(storage.MarkFilter{FolderID: &id, Before: &before})
default:
rw.WriteHeader(http.StatusBadRequest)
return
}
}

View File

@ -24,7 +24,6 @@ import (
var routes []Route = []Route{ var routes []Route = []Route{
p("/", IndexHandler).ManualAuth(), p("/", IndexHandler).ManualAuth(),
p("/static/*path", StaticHandler).ManualAuth(), p("/static/*path", StaticHandler).ManualAuth(),
p("/fever", FeverHandler).ManualAuth(),
p("/api/status", StatusHandler), p("/api/status", StatusHandler),
p("/api/folders", FolderListHandler), p("/api/folders", FolderListHandler),

View File

@ -62,17 +62,11 @@ type ItemFilter struct {
FeedID *int64 FeedID *int64
Status *ItemStatus Status *ItemStatus
Search *string Search *string
IDs *[]int64
SinceID *int64
MaxID *int64
} }
type MarkFilter struct { type MarkFilter struct {
FolderID *int64 FolderID *int64
FeedID *int64 FeedID *int64
Before *time.Time
} }
func (s *Storage) CreateItems(items []Item) bool { func (s *Storage) CreateItems(items []Item) bool {
@ -151,25 +145,6 @@ func listQueryPredicate(filter ItemFilter) (string, []interface{}) {
args = append(args, strings.Join(terms, " ")) args = append(args, strings.Join(terms, " "))
} }
if filter.IDs != nil && len(*filter.IDs) > 0 {
qmarks := make([]string, len(*filter.IDs))
idargs := make([]interface{}, len(*filter.IDs))
for i, id := range *filter.IDs {
qmarks[i] = "?"
idargs[i] = id
}
cond = append(cond, "i.id in (" + strings.Join(qmarks, ",") + ")")
args = append(args, idargs...)
}
if filter.SinceID != nil {
cond = append(cond, "i.id > ?")
args = append(args, filter.SinceID)
}
if filter.MaxID != nil {
cond = append(cond, "i.id < ?")
args = append(args, filter.MaxID)
}
predicate := "1" predicate := "1"
if len(cond) > 0 { if len(cond) > 0 {
predicate = strings.Join(cond, " and ") predicate = strings.Join(cond, " and ")
@ -187,10 +162,6 @@ func (s *Storage) ListItems(filter ItemFilter, offset, limit int, newestFirst bo
order = "date asc" order = "date asc"
} }
if filter.IDs != nil || filter.SinceID != nil || filter.MaxID != nil {
order = "i.id asc"
}
query := fmt.Sprintf(` query := fmt.Sprintf(`
select select
i.id, i.guid, i.feed_id, i.title, i.link, i.description, i.id, i.guid, i.feed_id, i.title, i.link, i.description,