Refactor packages to have more idiomatic code base

This commit is contained in:
Frédéric Guillot 2018-01-02 22:04:48 -08:00
parent c39f2e1a8d
commit 320d1b0167
109 changed files with 449 additions and 402 deletions

View file

@ -7,14 +7,13 @@ package api
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/server/api/payload" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/server/core"
) )
// CreateCategory is the API handler to create a new category. // CreateCategory is the API handler to create a new category.
func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) CreateCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
category, err := payload.DecodeCategoryPayload(request.Body()) category, err := decodeCategoryPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
@ -41,14 +40,14 @@ func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, re
} }
// UpdateCategory is the API handler to update a category. // UpdateCategory is the API handler to update a category.
func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
categoryID, err := request.IntegerParam("categoryID") categoryID, err := request.IntegerParam("categoryID")
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
} }
category, err := payload.DecodeCategoryPayload(request.Body()) category, err := decodeCategoryPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
@ -71,7 +70,7 @@ func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, re
} }
// GetCategories is the API handler to get a list of categories for a given user. // GetCategories is the API handler to get a list of categories for a given user.
func (c *Controller) GetCategories(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetCategories(ctx *handler.Context, request *handler.Request, response *handler.Response) {
categories, err := c.store.Categories(ctx.UserID()) categories, err := c.store.Categories(ctx.UserID())
if err != nil { if err != nil {
response.JSON().ServerError(errors.New("Unable to fetch categories")) response.JSON().ServerError(errors.New("Unable to fetch categories"))
@ -82,7 +81,7 @@ func (c *Controller) GetCategories(ctx *core.Context, request *core.Request, res
} }
// RemoveCategory is the API handler to remove a category. // RemoveCategory is the API handler to remove a category.
func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RemoveCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
categoryID, err := request.IntegerParam("categoryID") categoryID, err := request.IntegerParam("categoryID")
if err != nil { if err != nil {

View file

@ -7,13 +7,12 @@ package api
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/api/payload"
"github.com/miniflux/miniflux/server/core"
) )
// GetFeedEntry is the API handler to get a single feed entry. // GetFeedEntry is the API handler to get a single feed entry.
func (c *Controller) GetFeedEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetFeedEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
@ -46,7 +45,7 @@ func (c *Controller) GetFeedEntry(ctx *core.Context, request *core.Request, resp
} }
// GetEntry is the API handler to get a single entry. // GetEntry is the API handler to get a single entry.
func (c *Controller) GetEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
if err != nil { if err != nil {
@ -72,7 +71,7 @@ func (c *Controller) GetEntry(ctx *core.Context, request *core.Request, response
} }
// GetFeedEntries is the API handler to get all feed entries. // GetFeedEntries is the API handler to get all feed entries.
func (c *Controller) GetFeedEntries(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetFeedEntries(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
@ -127,11 +126,11 @@ func (c *Controller) GetFeedEntries(ctx *core.Context, request *core.Request, re
return return
} }
response.JSON().Standard(&payload.EntriesResponse{Total: count, Entries: entries}) response.JSON().Standard(&entriesResponse{Total: count, Entries: entries})
} }
// GetEntries is the API handler to fetch entries. // GetEntries is the API handler to fetch entries.
func (c *Controller) GetEntries(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetEntries(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
status := request.QueryStringParam("status", "") status := request.QueryStringParam("status", "")
@ -180,14 +179,14 @@ func (c *Controller) GetEntries(ctx *core.Context, request *core.Request, respon
return return
} }
response.JSON().Standard(&payload.EntriesResponse{Total: count, Entries: entries}) response.JSON().Standard(&entriesResponse{Total: count, Entries: entries})
} }
// SetEntryStatus is the API handler to change the status of entries. // SetEntryStatus is the API handler to change the status of entries.
func (c *Controller) SetEntryStatus(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) SetEntryStatus(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
entryIDs, status, err := payload.DecodeEntryStatusPayload(request.Body()) entryIDs, status, err := decodeEntryStatusPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(errors.New("Invalid JSON payload")) response.JSON().BadRequest(errors.New("Invalid JSON payload"))
return return
@ -207,7 +206,7 @@ func (c *Controller) SetEntryStatus(ctx *core.Context, request *core.Request, re
} }
// ToggleBookmark is the API handler to toggle bookmark status. // ToggleBookmark is the API handler to toggle bookmark status.
func (c *Controller) ToggleBookmark(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ToggleBookmark(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
if err != nil { if err != nil {

View file

@ -7,14 +7,13 @@ package api
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/server/api/payload" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/server/core"
) )
// CreateFeed is the API handler to create a new feed. // CreateFeed is the API handler to create a new feed.
func (c *Controller) CreateFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) CreateFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedURL, categoryID, err := payload.DecodeFeedCreationPayload(request.Body()) feedURL, categoryID, err := decodeFeedCreationPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
@ -54,7 +53,7 @@ func (c *Controller) CreateFeed(ctx *core.Context, request *core.Request, respon
} }
// RefreshFeed is the API handler to refresh a feed. // RefreshFeed is the API handler to refresh a feed.
func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RefreshFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
@ -77,7 +76,7 @@ func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, respo
} }
// UpdateFeed is the API handler that is used to update a feed. // UpdateFeed is the API handler that is used to update a feed.
func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
@ -85,7 +84,7 @@ func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, respon
return return
} }
newFeed, err := payload.DecodeFeedModificationPayload(request.Body()) newFeed, err := decodeFeedModificationPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
@ -123,7 +122,7 @@ func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, respon
} }
// GetFeeds is the API handler that get all feeds that belongs to the given user. // GetFeeds is the API handler that get all feeds that belongs to the given user.
func (c *Controller) GetFeeds(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetFeeds(ctx *handler.Context, request *handler.Request, response *handler.Response) {
feeds, err := c.store.Feeds(ctx.UserID()) feeds, err := c.store.Feeds(ctx.UserID())
if err != nil { if err != nil {
response.JSON().ServerError(errors.New("Unable to fetch feeds from the database")) response.JSON().ServerError(errors.New("Unable to fetch feeds from the database"))
@ -134,7 +133,7 @@ func (c *Controller) GetFeeds(ctx *core.Context, request *core.Request, response
} }
// GetFeed is the API handler to get a feed. // GetFeed is the API handler to get a feed.
func (c *Controller) GetFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
@ -157,7 +156,7 @@ func (c *Controller) GetFeed(ctx *core.Context, request *core.Request, response
} }
// RemoveFeed is the API handler to remove a feed. // RemoveFeed is the API handler to remove a feed.
func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RemoveFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {

View file

@ -7,12 +7,11 @@ package api
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/server/api/payload" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/server/core"
) )
// FeedIcon returns a feed icon. // FeedIcon returns a feed icon.
func (c *Controller) FeedIcon(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) FeedIcon(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
@ -36,7 +35,7 @@ func (c *Controller) FeedIcon(ctx *core.Context, request *core.Request, response
return return
} }
response.JSON().Standard(&payload.FeedIcon{ response.JSON().Standard(&feedIcon{
ID: icon.ID, ID: icon.ID,
MimeType: icon.MimeType, MimeType: icon.MimeType,
Data: icon.DataURL(), Data: icon.DataURL(),

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package payload package api
import ( import (
"encoding/json" "encoding/json"
@ -12,21 +12,18 @@ import (
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
) )
// FeedIcon represents the feed icon response. type feedIcon struct {
type FeedIcon struct {
ID int64 `json:"id"` ID int64 `json:"id"`
MimeType string `json:"mime_type"` MimeType string `json:"mime_type"`
Data string `json:"data"` Data string `json:"data"`
} }
// EntriesResponse represents the response sent when fetching entries. type entriesResponse struct {
type EntriesResponse struct {
Total int `json:"total"` Total int `json:"total"`
Entries model.Entries `json:"entries"` Entries model.Entries `json:"entries"`
} }
// DecodeUserPayload unserialize JSON user object. func decodeUserPayload(data io.Reader) (*model.User, error) {
func DecodeUserPayload(data io.Reader) (*model.User, error) {
var user model.User var user model.User
decoder := json.NewDecoder(data) decoder := json.NewDecoder(data)
@ -37,8 +34,7 @@ func DecodeUserPayload(data io.Reader) (*model.User, error) {
return &user, nil return &user, nil
} }
// DecodeURLPayload unserialize JSON subscription object. func decodeURLPayload(data io.Reader) (string, error) {
func DecodeURLPayload(data io.Reader) (string, error) {
type payload struct { type payload struct {
URL string `json:"url"` URL string `json:"url"`
} }
@ -52,8 +48,7 @@ func DecodeURLPayload(data io.Reader) (string, error) {
return p.URL, nil return p.URL, nil
} }
// DecodeEntryStatusPayload unserialize JSON entry statuses object. func decodeEntryStatusPayload(data io.Reader) ([]int64, string, error) {
func DecodeEntryStatusPayload(data io.Reader) ([]int64, string, error) {
type payload struct { type payload struct {
EntryIDs []int64 `json:"entry_ids"` EntryIDs []int64 `json:"entry_ids"`
Status string `json:"status"` Status string `json:"status"`
@ -68,8 +63,7 @@ func DecodeEntryStatusPayload(data io.Reader) ([]int64, string, error) {
return p.EntryIDs, p.Status, nil return p.EntryIDs, p.Status, nil
} }
// DecodeFeedCreationPayload unserialize JSON feed creation object. func decodeFeedCreationPayload(data io.Reader) (string, int64, error) {
func DecodeFeedCreationPayload(data io.Reader) (string, int64, error) {
type payload struct { type payload struct {
FeedURL string `json:"feed_url"` FeedURL string `json:"feed_url"`
CategoryID int64 `json:"category_id"` CategoryID int64 `json:"category_id"`
@ -84,8 +78,7 @@ func DecodeFeedCreationPayload(data io.Reader) (string, int64, error) {
return p.FeedURL, p.CategoryID, nil return p.FeedURL, p.CategoryID, nil
} }
// DecodeFeedModificationPayload unserialize JSON feed object. func decodeFeedModificationPayload(data io.Reader) (*model.Feed, error) {
func DecodeFeedModificationPayload(data io.Reader) (*model.Feed, error) {
var feed model.Feed var feed model.Feed
decoder := json.NewDecoder(data) decoder := json.NewDecoder(data)
@ -96,8 +89,7 @@ func DecodeFeedModificationPayload(data io.Reader) (*model.Feed, error) {
return &feed, nil return &feed, nil
} }
// DecodeCategoryPayload unserialize JSON category object. func decodeCategoryPayload(data io.Reader) (*model.Category, error) {
func DecodeCategoryPayload(data io.Reader) (*model.Category, error) {
var category model.Category var category model.Category
decoder := json.NewDecoder(data) decoder := json.NewDecoder(data)

View file

@ -8,14 +8,13 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/reader/subscription" "github.com/miniflux/miniflux/reader/subscription"
"github.com/miniflux/miniflux/server/api/payload"
"github.com/miniflux/miniflux/server/core"
) )
// GetSubscriptions is the API handler to find subscriptions. // GetSubscriptions is the API handler to find subscriptions.
func (c *Controller) GetSubscriptions(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) GetSubscriptions(ctx *handler.Context, request *handler.Request, response *handler.Response) {
websiteURL, err := payload.DecodeURLPayload(request.Body()) websiteURL, err := decodeURLPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return

View file

@ -7,18 +7,17 @@ package api
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/server/api/payload" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/server/core"
) )
// CreateUser is the API handler to create a new user. // CreateUser is the API handler to create a new user.
func (c *Controller) CreateUser(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) CreateUser(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if !ctx.IsAdminUser() { if !ctx.IsAdminUser() {
response.JSON().Forbidden() response.JSON().Forbidden()
return return
} }
user, err := payload.DecodeUserPayload(request.Body()) user, err := decodeUserPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
@ -45,7 +44,7 @@ func (c *Controller) CreateUser(ctx *core.Context, request *core.Request, respon
} }
// UpdateUser is the API handler to update the given user. // UpdateUser is the API handler to update the given user.
func (c *Controller) UpdateUser(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateUser(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if !ctx.IsAdminUser() { if !ctx.IsAdminUser() {
response.JSON().Forbidden() response.JSON().Forbidden()
return return
@ -57,7 +56,7 @@ func (c *Controller) UpdateUser(ctx *core.Context, request *core.Request, respon
return return
} }
user, err := payload.DecodeUserPayload(request.Body()) user, err := decodeUserPayload(request.Body())
if err != nil { if err != nil {
response.JSON().BadRequest(err) response.JSON().BadRequest(err)
return return
@ -89,7 +88,7 @@ func (c *Controller) UpdateUser(ctx *core.Context, request *core.Request, respon
} }
// Users is the API handler to get the list of users. // Users is the API handler to get the list of users.
func (c *Controller) Users(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Users(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if !ctx.IsAdminUser() { if !ctx.IsAdminUser() {
response.JSON().Forbidden() response.JSON().Forbidden()
return return
@ -105,7 +104,7 @@ func (c *Controller) Users(ctx *core.Context, request *core.Request, response *c
} }
// UserByID is the API handler to fetch the given user by the ID. // UserByID is the API handler to fetch the given user by the ID.
func (c *Controller) UserByID(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UserByID(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if !ctx.IsAdminUser() { if !ctx.IsAdminUser() {
response.JSON().Forbidden() response.JSON().Forbidden()
return return
@ -132,7 +131,7 @@ func (c *Controller) UserByID(ctx *core.Context, request *core.Request, response
} }
// UserByUsername is the API handler to fetch the given user by the username. // UserByUsername is the API handler to fetch the given user by the username.
func (c *Controller) UserByUsername(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UserByUsername(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if !ctx.IsAdminUser() { if !ctx.IsAdminUser() {
response.JSON().Forbidden() response.JSON().Forbidden()
return return
@ -154,7 +153,7 @@ func (c *Controller) UserByUsername(ctx *core.Context, request *core.Request, re
} }
// RemoveUser is the API handler to remove an existing user. // RemoveUser is the API handler to remove an existing user.
func (c *Controller) RemoveUser(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RemoveUser(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if !ctx.IsAdminUser() { if !ctx.IsAdminUser() {
response.JSON().Forbidden() response.JSON().Forbidden()
return return

58
cli/cli.go Normal file
View file

@ -0,0 +1,58 @@
// Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package cli
import (
"flag"
"fmt"
"github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/daemon"
"github.com/miniflux/miniflux/storage"
"github.com/miniflux/miniflux/version"
)
// Parse parses command line arguments.
func Parse() {
flagInfo := flag.Bool("info", false, "Show application information")
flagVersion := flag.Bool("version", false, "Show application version")
flagMigrate := flag.Bool("migrate", false, "Migrate database schema")
flagFlushSessions := flag.Bool("flush-sessions", false, "Flush all sessions (disconnect users)")
flagCreateAdmin := flag.Bool("create-admin", false, "Create admin user")
flag.Parse()
cfg := config.NewConfig()
store := storage.NewStorage(
cfg.Get("DATABASE_URL", config.DefaultDatabaseURL),
cfg.GetInt("DATABASE_MAX_CONNS", config.DefaultDatabaseMaxConns),
)
if *flagInfo {
info()
return
}
if *flagVersion {
fmt.Println(version.Version)
return
}
if *flagMigrate {
store.Migrate()
return
}
if *flagFlushSessions {
flushSessions(store)
return
}
if *flagCreateAdmin {
createAdmin(store)
return
}
daemon.Run(cfg, store)
}

52
cli/create_admin.go Normal file
View file

@ -0,0 +1,52 @@
// Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package cli
import (
"bufio"
"fmt"
"os"
"strings"
"github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/storage"
"golang.org/x/crypto/ssh/terminal"
)
func askCredentials() (string, string) {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter Username: ")
username, _ := reader.ReadString('\n')
fmt.Print("Enter Password: ")
bytePassword, _ := terminal.ReadPassword(0)
fmt.Printf("\n")
return strings.TrimSpace(username), strings.TrimSpace(string(bytePassword))
}
func createAdmin(store *storage.Storage) {
user := &model.User{
Username: os.Getenv("ADMIN_USERNAME"),
Password: os.Getenv("ADMIN_PASSWORD"),
IsAdmin: true,
}
if user.Username == "" || user.Password == "" {
user.Username, user.Password = askCredentials()
}
if err := user.ValidateUserCreation(); err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := store.CreateUser(user); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

20
cli/flush_sessions.go Normal file
View file

@ -0,0 +1,20 @@
// Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package cli
import (
"fmt"
"os"
"github.com/miniflux/miniflux/storage"
)
func flushSessions(store *storage.Storage) {
fmt.Println("Flushing all sessions (disconnect users)")
if err := store.FlushAllSessions(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

18
cli/info.go Normal file
View file

@ -0,0 +1,18 @@
// Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package cli
import (
"fmt"
"runtime"
"github.com/miniflux/miniflux/version"
)
func info() {
fmt.Println("Version:", version.Version)
fmt.Println("Build Date:", version.BuildDate)
fmt.Println("Go Version:", runtime.Version())
}

46
daemon/daemon.go Normal file
View file

@ -0,0 +1,46 @@
// Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package daemon
import (
"context"
"os"
"os/signal"
"time"
"github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/reader/feed"
"github.com/miniflux/miniflux/scheduler"
"github.com/miniflux/miniflux/storage"
)
// Run starts the daemon.
func Run(cfg *config.Config, store *storage.Storage) {
logger.Info("Starting Miniflux...")
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
feedHandler := feed.NewFeedHandler(store)
pool := scheduler.NewWorkerPool(feedHandler, cfg.GetInt("WORKER_POOL_SIZE", config.DefaultWorkerPoolSize))
server := newServer(cfg, store, pool, feedHandler)
scheduler.NewFeedScheduler(
store,
pool,
cfg.GetInt("POLLING_FREQUENCY", config.DefaultPollingFrequency),
cfg.GetInt("BATCH_SIZE", config.DefaultBatchSize),
)
scheduler.NewSessionScheduler(store, config.DefaultSessionCleanupFrequency)
<-stop
logger.Info("Shutting down the server...")
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
server.Shutdown(ctx)
store.Close()
logger.Info("Server gracefully stopped")
}

View file

@ -1,47 +1,46 @@
// Copyright 2017 Frédéric Guillot. All rights reserved. // Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package server package daemon
import ( import (
"net/http" "net/http"
"github.com/miniflux/miniflux/scheduler" "github.com/miniflux/miniflux/api"
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/fever"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/http/middleware"
"github.com/miniflux/miniflux/locale" "github.com/miniflux/miniflux/locale"
"github.com/miniflux/miniflux/reader/feed" "github.com/miniflux/miniflux/reader/feed"
"github.com/miniflux/miniflux/reader/opml" "github.com/miniflux/miniflux/reader/opml"
api_controller "github.com/miniflux/miniflux/server/api/controller" "github.com/miniflux/miniflux/scheduler"
"github.com/miniflux/miniflux/server/core"
"github.com/miniflux/miniflux/server/fever"
"github.com/miniflux/miniflux/server/middleware"
"github.com/miniflux/miniflux/server/template"
ui_controller "github.com/miniflux/miniflux/server/ui/controller"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
"github.com/miniflux/miniflux/template"
"github.com/miniflux/miniflux/ui"
"github.com/gorilla/mux" "github.com/gorilla/mux"
) )
func getRoutes(cfg *config.Config, store *storage.Storage, feedHandler *feed.Handler, pool *scheduler.WorkerPool) *mux.Router { func routes(cfg *config.Config, store *storage.Storage, feedHandler *feed.Handler, pool *scheduler.WorkerPool) *mux.Router {
router := mux.NewRouter() router := mux.NewRouter()
translator := locale.Load() translator := locale.Load()
templateEngine := template.NewEngine(cfg, router, translator) templateEngine := template.NewEngine(cfg, router, translator)
apiController := api_controller.NewController(store, feedHandler) apiController := api.NewController(store, feedHandler)
feverController := fever.NewController(store) feverController := fever.NewController(store)
uiController := ui_controller.NewController(cfg, store, pool, feedHandler, opml.NewHandler(store)) uiController := ui.NewController(cfg, store, pool, feedHandler, opml.NewHandler(store))
apiHandler := core.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain( apiHandler := handler.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain(
middleware.NewBasicAuthMiddleware(store).Handler, middleware.NewBasicAuthMiddleware(store).Handler,
)) ))
feverHandler := core.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain( feverHandler := handler.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain(
middleware.NewFeverMiddleware(store).Handler, middleware.NewFeverMiddleware(store).Handler,
)) ))
uiHandler := core.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain( uiHandler := handler.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain(
middleware.NewUserSessionMiddleware(store, router).Handler, middleware.NewUserSessionMiddleware(store, router).Handler,
middleware.NewSessionMiddleware(cfg, store).Handler, middleware.NewSessionMiddleware(cfg, store).Handler,
)) ))

View file

@ -1,30 +1,24 @@
// Copyright 2017 Frédéric Guillot. All rights reserved. // Copyright 2018 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package server package daemon
import ( import (
"crypto/tls" "crypto/tls"
"net/http" "net/http"
"time" "time"
"github.com/gorilla/mux"
"github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/scheduler"
"golang.org/x/crypto/acme/autocert"
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/reader/feed" "github.com/miniflux/miniflux/reader/feed"
"github.com/miniflux/miniflux/scheduler"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
"golang.org/x/crypto/acme/autocert"
) )
// NewServer returns a new HTTP server. func newServer(cfg *config.Config, store *storage.Storage, pool *scheduler.WorkerPool, feedHandler *feed.Handler) *http.Server {
func NewServer(cfg *config.Config, store *storage.Storage, pool *scheduler.WorkerPool, feedHandler *feed.Handler) *http.Server {
return startServer(cfg, getRoutes(cfg, store, feedHandler, pool))
}
func startServer(cfg *config.Config, handler *mux.Router) *http.Server {
certFile := cfg.Get("CERT_FILE", config.DefaultCertFile) certFile := cfg.Get("CERT_FILE", config.DefaultCertFile)
keyFile := cfg.Get("KEY_FILE", config.DefaultKeyFile) keyFile := cfg.Get("KEY_FILE", config.DefaultKeyFile)
certDomain := cfg.Get("CERT_DOMAIN", config.DefaultCertDomain) certDomain := cfg.Get("CERT_DOMAIN", config.DefaultCertDomain)
@ -34,7 +28,7 @@ func startServer(cfg *config.Config, handler *mux.Router) *http.Server {
WriteTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second,
IdleTimeout: 60 * time.Second, IdleTimeout: 60 * time.Second,
Addr: cfg.Get("LISTEN_ADDR", config.DefaultListenAddr), Addr: cfg.Get("LISTEN_ADDR", config.DefaultListenAddr),
Handler: handler, Handler: routes(cfg, store, feedHandler, pool),
} }
if certDomain != "" && certCache != "" { if certDomain != "" && certCache != "" {

View file

@ -9,10 +9,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/integration" "github.com/miniflux/miniflux/integration"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/core"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
) )
@ -129,7 +129,7 @@ type Controller struct {
} }
// Handler handles Fever API calls // Handler handles Fever API calls
func (c *Controller) Handler(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Handler(ctx *handler.Context, request *handler.Request, response *handler.Response) {
switch { switch {
case request.HasQueryParam("groups"): case request.HasQueryParam("groups"):
c.handleGroups(ctx, request, response) c.handleGroups(ctx, request, response)
@ -174,7 +174,7 @@ The “Sparks” super group is not included in this response and is composed of
is_spark equal to 1. is_spark equal to 1.
*/ */
func (c *Controller) handleGroups(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleGroups(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Fetching groups for userID=%d", userID) logger.Debug("[Fever] Fetching groups for userID=%d", userID)
@ -224,7 +224,7 @@ should be limited to feeds with an is_spark equal to 0.
For the Sparks super group the items should be limited to feeds with an is_spark equal to 1. For the Sparks super group the items should be limited to feeds with an is_spark equal to 1.
*/ */
func (c *Controller) handleFeeds(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleFeeds(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Fetching feeds for userID=%d", userID) logger.Debug("[Fever] Fetching feeds for userID=%d", userID)
@ -277,7 +277,7 @@ A PHP/HTML example:
echo '<img src="data:'.$favicon['data'].'">'; echo '<img src="data:'.$favicon['data'].'">';
*/ */
func (c *Controller) handleFavicons(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleFavicons(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Fetching favicons for userID=%d", userID) logger.Debug("[Fever] Fetching favicons for userID=%d", userID)
@ -330,7 +330,7 @@ Three optional arguments control determine the items included in the response.
(added in API version 2) (added in API version 2)
*/ */
func (c *Controller) handleItems(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleItems(ctx *handler.Context, request *handler.Request, response *handler.Response) {
var result itemsResponse var result itemsResponse
userID := ctx.UserID() userID := ctx.UserID()
@ -414,7 +414,7 @@ with the remote Fever installation.
A request with the unread_item_ids argument will return one additional member: A request with the unread_item_ids argument will return one additional member:
unread_item_ids (string/comma-separated list of positive integers) unread_item_ids (string/comma-separated list of positive integers)
*/ */
func (c *Controller) handleUnreadItems(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleUnreadItems(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Fetching unread items for userID=%d", userID) logger.Debug("[Fever] Fetching unread items for userID=%d", userID)
@ -445,7 +445,7 @@ with the remote Fever installation.
saved_item_ids (string/comma-separated list of positive integers) saved_item_ids (string/comma-separated list of positive integers)
*/ */
func (c *Controller) handleSavedItems(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleSavedItems(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Fetching saved items for userID=%d", userID) logger.Debug("[Fever] Fetching saved items for userID=%d", userID)
@ -473,7 +473,7 @@ func (c *Controller) handleSavedItems(ctx *core.Context, request *core.Request,
as=? where ? is replaced with read, saved or unsaved as=? where ? is replaced with read, saved or unsaved
id=? where ? is replaced with the id of the item to modify id=? where ? is replaced with the id of the item to modify
*/ */
func (c *Controller) handleWriteItems(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleWriteItems(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Receiving mark=item call for userID=%d", userID) logger.Debug("[Fever] Receiving mark=item call for userID=%d", userID)
@ -527,7 +527,7 @@ func (c *Controller) handleWriteItems(ctx *core.Context, request *core.Request,
id=? where ? is replaced with the id of the feed or group to modify id=? where ? is replaced with the id of the feed or group to modify
before=? where ? is replaced with the Unix timestamp of the the local clients most recent items API request before=? where ? is replaced with the Unix timestamp of the the local clients most recent items API request
*/ */
func (c *Controller) handleWriteFeeds(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleWriteFeeds(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Receiving mark=feed call for userID=%d", userID) logger.Debug("[Fever] Receiving mark=feed call for userID=%d", userID)
@ -567,7 +567,7 @@ func (c *Controller) handleWriteFeeds(ctx *core.Context, request *core.Request,
id=? where ? is replaced with the id of the feed or group to modify id=? where ? is replaced with the id of the feed or group to modify
before=? where ? is replaced with the Unix timestamp of the the local clients most recent items API request before=? where ? is replaced with the Unix timestamp of the the local clients most recent items API request
*/ */
func (c *Controller) handleWriteGroups(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) handleWriteGroups(ctx *handler.Context, request *handler.Request, response *handler.Response) {
userID := ctx.UserID() userID := ctx.UserID()
logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID) logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID)

View file

@ -8,7 +8,7 @@ import (
"encoding/base64" "encoding/base64"
"strings" "strings"
"github.com/miniflux/miniflux/server/route" "github.com/miniflux/miniflux/http/route"
"github.com/miniflux/miniflux/url" "github.com/miniflux/miniflux/url"
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"

View file

@ -111,10 +111,10 @@ func generateFile(serializer, pkg, mapName, pattern, output string) {
func main() { func main() {
generateFile("none", "sql", "SqlMap", "sql/*.sql", "sql/sql.go") generateFile("none", "sql", "SqlMap", "sql/*.sql", "sql/sql.go")
generateFile("base64", "static", "Binaries", "server/static/bin/*", "server/static/bin.go") generateFile("base64", "static", "Binaries", "ui/static/bin/*", "ui/static/bin.go")
generateFile("css", "static", "Stylesheets", "server/static/css/*.css", "server/static/css.go") generateFile("css", "static", "Stylesheets", "ui/static/css/*.css", "ui/static/css.go")
generateFile("js", "static", "Javascript", "server/static/js/*.js", "server/static/js.go") generateFile("js", "static", "Javascript", "ui/static/js/*.js", "ui/static/js.go")
generateFile("none", "template", "templateViewsMap", "server/template/html/*.html", "server/template/views.go") generateFile("none", "template", "templateViewsMap", "template/html/*.html", "template/views.go")
generateFile("none", "template", "templateCommonMap", "server/template/html/common/*.html", "server/template/common.go") generateFile("none", "template", "templateCommonMap", "template/html/common/*.html", "template/common.go")
generateFile("none", "locale", "translations", "locale/translations/*.json", "locale/translations.go") generateFile("none", "locale", "translations", "locale/translations/*.json", "locale/translations.go")
} }

View file

@ -2,17 +2,17 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"net/http" "net/http"
"github.com/miniflux/miniflux/crypto" "github.com/miniflux/miniflux/crypto"
"github.com/miniflux/miniflux/http/middleware"
"github.com/miniflux/miniflux/http/route"
"github.com/miniflux/miniflux/locale" "github.com/miniflux/miniflux/locale"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/middleware"
"github.com/miniflux/miniflux/server/route"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -155,6 +155,6 @@ func (c *Context) Route(name string, args ...interface{}) string {
} }
// NewContext creates a new Context. // NewContext creates a new Context.
func NewContext(w http.ResponseWriter, r *http.Request, store *storage.Storage, router *mux.Router, translator *locale.Translator) *Context { func NewContext(r *http.Request, store *storage.Storage, router *mux.Router, translator *locale.Translator) *Context {
return &Context{writer: w, request: r, store: store, router: router, translator: translator} return &Context{request: r, store: store, router: router, translator: translator}
} }

View file

@ -2,26 +2,26 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"net/http" "net/http"
"time" "time"
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/http/middleware"
"github.com/miniflux/miniflux/locale" "github.com/miniflux/miniflux/locale"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/middleware"
"github.com/miniflux/miniflux/server/template"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
"github.com/miniflux/miniflux/template"
"github.com/miniflux/miniflux/timer" "github.com/miniflux/miniflux/timer"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/tomasen/realip" "github.com/tomasen/realip"
) )
// HandlerFunc is an application HTTP handler. // ControllerFunc is an application HTTP handler.
type HandlerFunc func(ctx *Context, request *Request, response *Response) type ControllerFunc func(ctx *Context, request *Request, response *Response)
// Handler manages HTTP handlers and middlewares. // Handler manages HTTP handlers and middlewares.
type Handler struct { type Handler struct {
@ -34,7 +34,7 @@ type Handler struct {
} }
// Use is a wrapper around an HTTP handler. // Use is a wrapper around an HTTP handler.
func (h *Handler) Use(f HandlerFunc) http.Handler { func (h *Handler) Use(f ControllerFunc) http.Handler {
return h.middleware.WrapFunc(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return h.middleware.WrapFunc(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer timer.ExecutionTime(time.Now(), r.URL.Path) defer timer.ExecutionTime(time.Now(), r.URL.Path)
logger.Debug("[HTTP] %s %s %s", realip.RealIP(r), r.Method, r.URL.Path) logger.Debug("[HTTP] %s %s %s", realip.RealIP(r), r.Method, r.URL.Path)
@ -43,8 +43,8 @@ func (h *Handler) Use(f HandlerFunc) http.Handler {
h.cfg.IsHTTPS = true h.cfg.IsHTTPS = true
} }
ctx := NewContext(w, r, h.store, h.router, h.translator) ctx := NewContext(r, h.store, h.router, h.translator)
request := NewRequest(w, r) request := NewRequest(r)
response := NewResponse(w, r, h.template) response := NewResponse(w, r, h.template)
if ctx.IsAuthenticated() { if ctx.IsAuthenticated() {

View file

@ -2,13 +2,13 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"net/http" "net/http"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/template" "github.com/miniflux/miniflux/template"
) )
// HTMLResponse handles HTML responses. // HTMLResponse handles HTML responses.

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"encoding/json" "encoding/json"

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"fmt" "fmt"
@ -17,7 +17,6 @@ import (
// Request is a thin wrapper around "http.Request". // Request is a thin wrapper around "http.Request".
type Request struct { type Request struct {
writer http.ResponseWriter
request *http.Request request *http.Request
} }
@ -119,7 +118,7 @@ func (r *Request) HasQueryParam(param string) bool {
return ok return ok
} }
// NewRequest returns a new Request struct. // NewRequest returns a new Request.
func NewRequest(w http.ResponseWriter, r *http.Request) *Request { func NewRequest(r *http.Request) *Request {
return &Request{writer: w, request: r} return &Request{r}
} }

View file

@ -2,13 +2,13 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"net/http" "net/http"
"time" "time"
"github.com/miniflux/miniflux/server/template" "github.com/miniflux/miniflux/template"
) )
// Response handles HTTP responses. // Response handles HTTP responses.

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package core package handler
import ( import (
"fmt" "fmt"

View file

@ -9,9 +9,9 @@ import (
"net/http" "net/http"
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/http/cookie"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/cookie"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
) )

View file

@ -8,10 +8,10 @@ import (
"context" "context"
"net/http" "net/http"
"github.com/miniflux/miniflux/http/cookie"
"github.com/miniflux/miniflux/http/route"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/cookie"
"github.com/miniflux/miniflux/server/route"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
"github.com/gorilla/mux" "github.com/gorilla/mux"

View file

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT. // Code generated by go generate; DO NOT EDIT.
// 2017-12-31 18:38:42.071995118 -0800 PST m=+0.052826276 // 2018-01-02 21:59:10.103098936 -0800 PST m=+0.030474265
package locale package locale

136
main.go
View file

@ -6,140 +6,18 @@ package main
//go:generate go run generate.go //go:generate go run generate.go
//go:generate gofmt -s -w sql/sql.go //go:generate gofmt -s -w sql/sql.go
//go:generate gofmt -s -w server/static/css.go //go:generate gofmt -s -w ui/static/css.go
//go:generate gofmt -s -w server/static/bin.go //go:generate gofmt -s -w ui/static/bin.go
//go:generate gofmt -s -w server/static/js.go //go:generate gofmt -s -w ui/static/js.go
//go:generate gofmt -s -w server/template/views.go //go:generate gofmt -s -w template/views.go
//go:generate gofmt -s -w server/template/common.go //go:generate gofmt -s -w template/common.go
//go:generate gofmt -s -w locale/translations.go //go:generate gofmt -s -w locale/translations.go
import ( import (
"bufio"
"context"
"flag"
"fmt"
"os"
"os/signal"
"runtime"
"strings"
"time"
"github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/reader/feed"
"github.com/miniflux/miniflux/scheduler"
"github.com/miniflux/miniflux/server"
"github.com/miniflux/miniflux/storage"
"github.com/miniflux/miniflux/version"
_ "github.com/lib/pq" _ "github.com/lib/pq"
"golang.org/x/crypto/ssh/terminal" "github.com/miniflux/miniflux/cli"
) )
func run(cfg *config.Config, store *storage.Storage) {
logger.Info("Starting Miniflux...")
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt)
feedHandler := feed.NewFeedHandler(store)
pool := scheduler.NewWorkerPool(feedHandler, cfg.GetInt("WORKER_POOL_SIZE", config.DefaultWorkerPoolSize))
server := server.NewServer(cfg, store, pool, feedHandler)
scheduler.NewFeedScheduler(
store,
pool,
cfg.GetInt("POLLING_FREQUENCY", config.DefaultPollingFrequency),
cfg.GetInt("BATCH_SIZE", config.DefaultBatchSize),
)
scheduler.NewSessionScheduler(store, config.DefaultSessionCleanupFrequency)
<-stop
logger.Info("Shutting down the server...")
ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
server.Shutdown(ctx)
store.Close()
logger.Info("Server gracefully stopped")
}
func askCredentials() (string, string) {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter Username: ")
username, _ := reader.ReadString('\n')
fmt.Print("Enter Password: ")
bytePassword, _ := terminal.ReadPassword(0)
fmt.Printf("\n")
return strings.TrimSpace(username), strings.TrimSpace(string(bytePassword))
}
func main() { func main() {
flagInfo := flag.Bool("info", false, "Show application information") cli.Parse()
flagVersion := flag.Bool("version", false, "Show application version")
flagMigrate := flag.Bool("migrate", false, "Migrate database schema")
flagFlushSessions := flag.Bool("flush-sessions", false, "Flush all sessions (disconnect users)")
flagCreateAdmin := flag.Bool("create-admin", false, "Create admin user")
flag.Parse()
cfg := config.NewConfig()
store := storage.NewStorage(
cfg.Get("DATABASE_URL", config.DefaultDatabaseURL),
cfg.GetInt("DATABASE_MAX_CONNS", config.DefaultDatabaseMaxConns),
)
if *flagInfo {
fmt.Println("Version:", version.Version)
fmt.Println("Build Date:", version.BuildDate)
fmt.Println("Go Version:", runtime.Version())
return
}
if *flagVersion {
fmt.Println(version.Version)
return
}
if *flagMigrate {
store.Migrate()
return
}
if *flagFlushSessions {
fmt.Println("Flushing all sessions (disconnect users)")
if err := store.FlushAllSessions(); err != nil {
fmt.Println(err)
os.Exit(1)
}
return
}
if *flagCreateAdmin {
user := &model.User{
Username: os.Getenv("ADMIN_USERNAME"),
Password: os.Getenv("ADMIN_PASSWORD"),
IsAdmin: true,
}
if user.Username == "" || user.Password == "" {
user.Username, user.Password = askCredentials()
}
if err := user.ValidateUserCreation(); err != nil {
fmt.Println(err)
os.Exit(1)
}
if err := store.CreateUser(user); err != nil {
fmt.Println(err)
os.Exit(1)
}
return
}
run(cfg, store)
} }

View file

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT. // Code generated by go generate; DO NOT EDIT.
// 2017-12-24 14:32:38.84708161 -0800 PST m=+0.004106505 // 2018-01-02 21:59:10.075345511 -0800 PST m=+0.002720840
package sql package sql

View file

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT. // Code generated by go generate; DO NOT EDIT.
// 2017-12-31 18:38:42.07097409 -0800 PST m=+0.051805248 // 2018-01-02 21:59:10.101985953 -0800 PST m=+0.029361282
package template package template

View file

@ -15,10 +15,10 @@ import (
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/duration" "github.com/miniflux/miniflux/duration"
"github.com/miniflux/miniflux/errors" "github.com/miniflux/miniflux/errors"
"github.com/miniflux/miniflux/filter"
"github.com/miniflux/miniflux/http/route"
"github.com/miniflux/miniflux/locale" "github.com/miniflux/miniflux/locale"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/route"
"github.com/miniflux/miniflux/server/ui/filter"
"github.com/miniflux/miniflux/url" "github.com/miniflux/miniflux/url"
"github.com/gorilla/mux" "github.com/gorilla/mux"

View file

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT. // Code generated by go generate; DO NOT EDIT.
// 2017-12-31 18:38:42.048775793 -0800 PST m=+0.029606951 // 2018-01-02 21:59:10.091229271 -0800 PST m=+0.018604600
package template package template

View file

@ -2,15 +2,15 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/version" "github.com/miniflux/miniflux/version"
) )
// AboutPage shows the about page. // AboutPage shows the about page.
func (c *Controller) AboutPage(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) AboutPage(ctx *handler.Context, request *handler.Request, response *handler.Response) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
response.HTML().ServerError(err) response.HTML().ServerError(err)

View file

@ -2,19 +2,19 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/ui/form"
"github.com/miniflux/miniflux/server/ui/form"
) )
// ShowCategories shows the page with all categories. // ShowCategories shows the page with all categories.
func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowCategories(ctx *handler.Context, request *handler.Request, response *handler.Response) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
response.HTML().ServerError(err) response.HTML().ServerError(err)
@ -36,7 +36,7 @@ func (c *Controller) ShowCategories(ctx *core.Context, request *core.Request, re
} }
// ShowCategoryEntries shows all entries for the given category. // ShowCategoryEntries shows all entries for the given category.
func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowCategoryEntries(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
offset := request.QueryIntegerParam("offset", 0) offset := request.QueryIntegerParam("offset", 0)
@ -81,7 +81,7 @@ func (c *Controller) ShowCategoryEntries(ctx *core.Context, request *core.Reques
} }
// CreateCategory shows the form to create a new category. // CreateCategory shows the form to create a new category.
func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) CreateCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
response.HTML().ServerError(err) response.HTML().ServerError(err)
@ -94,7 +94,7 @@ func (c *Controller) CreateCategory(ctx *core.Context, request *core.Request, re
} }
// SaveCategory validate and save the new category into the database. // SaveCategory validate and save the new category into the database.
func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) SaveCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
@ -137,7 +137,7 @@ func (c *Controller) SaveCategory(ctx *core.Context, request *core.Request, resp
} }
// EditCategory shows the form to modify a category. // EditCategory shows the form to modify a category.
func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) EditCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
category, err := c.getCategoryFromURL(ctx, request, response) category, err := c.getCategoryFromURL(ctx, request, response)
@ -156,7 +156,7 @@ func (c *Controller) EditCategory(ctx *core.Context, request *core.Request, resp
} }
// UpdateCategory validate and update a category. // UpdateCategory validate and update a category.
func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
category, err := c.getCategoryFromURL(ctx, request, response) category, err := c.getCategoryFromURL(ctx, request, response)
@ -199,7 +199,7 @@ func (c *Controller) UpdateCategory(ctx *core.Context, request *core.Request, re
} }
// RemoveCategory delete a category from the database. // RemoveCategory delete a category from the database.
func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RemoveCategory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
category, err := c.getCategoryFromURL(ctx, request, response) category, err := c.getCategoryFromURL(ctx, request, response)
@ -215,7 +215,7 @@ func (c *Controller) RemoveCategory(ctx *core.Context, request *core.Request, re
response.Redirect(ctx.Route("categories")) response.Redirect(ctx.Route("categories"))
} }
func (c *Controller) getCategoryFromURL(ctx *core.Context, request *core.Request, response *core.Response) (*model.Category, error) { func (c *Controller) getCategoryFromURL(ctx *handler.Context, request *handler.Request, response *handler.Response) (*model.Category, error) {
categoryID, err := request.IntegerParam("categoryID") categoryID, err := request.IntegerParam("categoryID")
if err != nil { if err != nil {
response.HTML().BadRequest(err) response.HTML().BadRequest(err)
@ -237,7 +237,7 @@ func (c *Controller) getCategoryFromURL(ctx *core.Context, request *core.Request
return category, nil return category, nil
} }
func (c *Controller) getCategoryFormTemplateArgs(ctx *core.Context, user *model.User, category *model.Category, categoryForm *form.CategoryForm) (tplParams, error) { func (c *Controller) getCategoryFormTemplateArgs(ctx *handler.Context, user *model.User, category *model.Category, categoryForm *form.CategoryForm) (tplParams, error) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -2,15 +2,15 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/reader/feed" "github.com/miniflux/miniflux/reader/feed"
"github.com/miniflux/miniflux/reader/opml" "github.com/miniflux/miniflux/reader/opml"
"github.com/miniflux/miniflux/scheduler" "github.com/miniflux/miniflux/scheduler"
"github.com/miniflux/miniflux/server/core"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
) )
@ -33,7 +33,7 @@ type Controller struct {
opmlHandler *opml.Handler opmlHandler *opml.Handler
} }
func (c *Controller) getCommonTemplateArgs(ctx *core.Context) (tplParams, error) { func (c *Controller) getCommonTemplateArgs(ctx *handler.Context) (tplParams, error) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
builder := c.store.NewEntryQueryBuilder(user.ID) builder := c.store.NewEntryQueryBuilder(user.ID)
builder.WithStatus(model.EntryStatusUnread) builder.WithStatus(model.EntryStatusUnread)

View file

@ -2,24 +2,22 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/reader/sanitizer"
"github.com/miniflux/miniflux/integration" "github.com/miniflux/miniflux/integration"
"github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/reader/sanitizer"
"github.com/miniflux/miniflux/reader/scraper" "github.com/miniflux/miniflux/reader/scraper"
"github.com/miniflux/miniflux/server/core"
"github.com/miniflux/miniflux/server/ui/payload"
"github.com/miniflux/miniflux/storage" "github.com/miniflux/miniflux/storage"
) )
// FetchContent downloads the original HTML page and returns relevant contents. // FetchContent downloads the original HTML page and returns relevant contents.
func (c *Controller) FetchContent(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) FetchContent(ctx *handler.Context, request *handler.Request, response *handler.Response) {
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
if err != nil { if err != nil {
response.HTML().BadRequest(err) response.HTML().BadRequest(err)
@ -55,7 +53,7 @@ func (c *Controller) FetchContent(ctx *core.Context, request *core.Request, resp
} }
// SaveEntry send the link to external services. // SaveEntry send the link to external services.
func (c *Controller) SaveEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) SaveEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
if err != nil { if err != nil {
response.HTML().BadRequest(err) response.HTML().BadRequest(err)
@ -92,7 +90,7 @@ func (c *Controller) SaveEntry(ctx *core.Context, request *core.Request, respons
} }
// ShowFeedEntry shows a single feed entry in "feed" mode. // ShowFeedEntry shows a single feed entry in "feed" mode.
func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowFeedEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
@ -168,7 +166,7 @@ func (c *Controller) ShowFeedEntry(ctx *core.Context, request *core.Request, res
} }
// ShowCategoryEntry shows a single feed entry in "category" mode. // ShowCategoryEntry shows a single feed entry in "category" mode.
func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowCategoryEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
categoryID, err := request.IntegerParam("categoryID") categoryID, err := request.IntegerParam("categoryID")
@ -244,7 +242,7 @@ func (c *Controller) ShowCategoryEntry(ctx *core.Context, request *core.Request,
} }
// ShowUnreadEntry shows a single feed entry in "unread" mode. // ShowUnreadEntry shows a single feed entry in "unread" mode.
func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowUnreadEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
@ -314,7 +312,7 @@ func (c *Controller) ShowUnreadEntry(ctx *core.Context, request *core.Request, r
} }
// ShowReadEntry shows a single feed entry in "history" mode. // ShowReadEntry shows a single feed entry in "history" mode.
func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowReadEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
@ -374,7 +372,7 @@ func (c *Controller) ShowReadEntry(ctx *core.Context, request *core.Request, res
} }
// ShowStarredEntry shows a single feed entry in "starred" mode. // ShowStarredEntry shows a single feed entry in "starred" mode.
func (c *Controller) ShowStarredEntry(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowStarredEntry(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
@ -443,10 +441,10 @@ func (c *Controller) ShowStarredEntry(ctx *core.Context, request *core.Request,
} }
// UpdateEntriesStatus handles Ajax request to update the status for a list of entries. // UpdateEntriesStatus handles Ajax request to update the status for a list of entries.
func (c *Controller) UpdateEntriesStatus(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateEntriesStatus(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
entryIDs, status, err := payload.DecodeEntryStatusPayload(request.Body()) entryIDs, status, err := decodeEntryStatusPayload(request.Body())
if err != nil { if err != nil {
logger.Error("[Controller:UpdateEntryStatus] %v", err) logger.Error("[Controller:UpdateEntryStatus] %v", err)
response.JSON().BadRequest(nil) response.JSON().BadRequest(nil)

View file

@ -2,19 +2,19 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"errors" "errors"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/ui/form"
"github.com/miniflux/miniflux/server/ui/form"
) )
// RefreshAllFeeds refresh all feeds in the background for the current user. // RefreshAllFeeds refresh all feeds in the background for the current user.
func (c *Controller) RefreshAllFeeds(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RefreshAllFeeds(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
jobs, err := c.store.NewUserBatch(user.ID, c.store.CountFeeds(user.ID)) jobs, err := c.store.NewUserBatch(user.ID, c.store.CountFeeds(user.ID))
if err != nil { if err != nil {
@ -30,7 +30,7 @@ func (c *Controller) RefreshAllFeeds(ctx *core.Context, request *core.Request, r
} }
// ShowFeedsPage shows the page with all subscriptions. // ShowFeedsPage shows the page with all subscriptions.
func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowFeedsPage(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
@ -53,7 +53,7 @@ func (c *Controller) ShowFeedsPage(ctx *core.Context, request *core.Request, res
} }
// ShowFeedEntries shows all entries for the given feed. // ShowFeedEntries shows all entries for the given feed.
func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowFeedEntries(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
offset := request.QueryIntegerParam("offset", 0) offset := request.QueryIntegerParam("offset", 0)
@ -98,7 +98,7 @@ func (c *Controller) ShowFeedEntries(ctx *core.Context, request *core.Request, r
} }
// EditFeed shows the form to modify a subscription. // EditFeed shows the form to modify a subscription.
func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) EditFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
feed, err := c.getFeedFromURL(request, response, user) feed, err := c.getFeedFromURL(request, response, user)
@ -116,7 +116,7 @@ func (c *Controller) EditFeed(ctx *core.Context, request *core.Request, response
} }
// UpdateFeed update a subscription and redirect to the feed entries page. // UpdateFeed update a subscription and redirect to the feed entries page.
func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
feed, err := c.getFeedFromURL(request, response, user) feed, err := c.getFeedFromURL(request, response, user)
@ -151,7 +151,7 @@ func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, respon
} }
// RemoveFeed delete a subscription from the database and redirect to the list of feeds page. // RemoveFeed delete a subscription from the database and redirect to the list of feeds page.
func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RemoveFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
response.HTML().ServerError(err) response.HTML().ServerError(err)
@ -168,7 +168,7 @@ func (c *Controller) RemoveFeed(ctx *core.Context, request *core.Request, respon
} }
// RefreshFeed refresh a subscription and redirect to the feed entries page. // RefreshFeed refresh a subscription and redirect to the feed entries page.
func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RefreshFeed(ctx *handler.Context, request *handler.Request, response *handler.Response) {
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
response.HTML().BadRequest(err) response.HTML().BadRequest(err)
@ -183,7 +183,7 @@ func (c *Controller) RefreshFeed(ctx *core.Context, request *core.Request, respo
response.Redirect(ctx.Route("feedEntries", "feedID", feedID)) response.Redirect(ctx.Route("feedEntries", "feedID", feedID))
} }
func (c *Controller) getFeedFromURL(request *core.Request, response *core.Response, user *model.User) (*model.Feed, error) { func (c *Controller) getFeedFromURL(request *handler.Request, response *handler.Response, user *model.User) (*model.Feed, error) {
feedID, err := request.IntegerParam("feedID") feedID, err := request.IntegerParam("feedID")
if err != nil { if err != nil {
response.HTML().BadRequest(err) response.HTML().BadRequest(err)
@ -204,7 +204,7 @@ func (c *Controller) getFeedFromURL(request *core.Request, response *core.Respon
return feed, nil return feed, nil
} }
func (c *Controller) getFeedFormTemplateArgs(ctx *core.Context, user *model.User, feed *model.Feed, feedForm *form.FeedForm) (tplParams, error) { func (c *Controller) getFeedFormTemplateArgs(ctx *handler.Context, user *model.User, feed *model.Feed, feedForm *form.FeedForm) (tplParams, error) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -2,15 +2,15 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/core"
) )
// ShowHistoryPage renders the page with all read entries. // ShowHistoryPage renders the page with all read entries.
func (c *Controller) ShowHistoryPage(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowHistoryPage(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
offset := request.QueryIntegerParam("offset", 0) offset := request.QueryIntegerParam("offset", 0)
@ -48,7 +48,7 @@ func (c *Controller) ShowHistoryPage(ctx *core.Context, request *core.Request, r
} }
// FlushHistory changes all "read" items to "removed". // FlushHistory changes all "read" items to "removed".
func (c *Controller) FlushHistory(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) FlushHistory(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
err := c.store.FlushHistory(user.ID) err := c.store.FlushHistory(user.ID)

View file

@ -2,16 +2,16 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"time" "time"
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/http/handler"
) )
// ShowIcon shows the feed icon. // ShowIcon shows the feed icon.
func (c *Controller) ShowIcon(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowIcon(ctx *handler.Context, request *handler.Request, response *handler.Response) {
iconID, err := request.IntegerParam("iconID") iconID, err := request.IntegerParam("iconID")
if err != nil { if err != nil {
response.HTML().BadRequest(err) response.HTML().BadRequest(err)

View file

@ -2,18 +2,18 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"crypto/md5" "crypto/md5"
"fmt" "fmt"
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/server/ui/form" "github.com/miniflux/miniflux/ui/form"
) )
// ShowIntegrations renders the page with all external integrations. // ShowIntegrations renders the page with all external integrations.
func (c *Controller) ShowIntegrations(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowIntegrations(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
integration, err := c.store.Integration(user.ID) integration, err := c.store.Integration(user.ID)
if err != nil { if err != nil {
@ -51,7 +51,7 @@ func (c *Controller) ShowIntegrations(ctx *core.Context, request *core.Request,
} }
// UpdateIntegration updates integration settings. // UpdateIntegration updates integration settings.
func (c *Controller) UpdateIntegration(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateIntegration(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
integration, err := c.store.Integration(user.ID) integration, err := c.store.Integration(user.ID)
if err != nil { if err != nil {

View file

@ -2,19 +2,19 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/http/cookie"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/cookie" "github.com/miniflux/miniflux/ui/form"
"github.com/miniflux/miniflux/server/core"
"github.com/miniflux/miniflux/server/ui/form"
"github.com/tomasen/realip" "github.com/tomasen/realip"
) )
// ShowLoginPage shows the login form. // ShowLoginPage shows the login form.
func (c *Controller) ShowLoginPage(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowLoginPage(ctx *handler.Context, request *handler.Request, response *handler.Response) {
if ctx.IsAuthenticated() { if ctx.IsAuthenticated() {
response.Redirect(ctx.Route("unread")) response.Redirect(ctx.Route("unread"))
return return
@ -26,7 +26,7 @@ func (c *Controller) ShowLoginPage(ctx *core.Context, request *core.Request, res
} }
// CheckLogin validates the username/password and redirects the user to the unread page. // CheckLogin validates the username/password and redirects the user to the unread page.
func (c *Controller) CheckLogin(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) CheckLogin(ctx *handler.Context, request *handler.Request, response *handler.Response) {
authForm := form.NewAuthForm(request.Request()) authForm := form.NewAuthForm(request.Request())
tplParams := tplParams{ tplParams := tplParams{
"errorMessage": "Invalid username or password.", "errorMessage": "Invalid username or password.",
@ -64,7 +64,7 @@ func (c *Controller) CheckLogin(ctx *core.Context, request *core.Request, respon
} }
// Logout destroy the session and redirects the user to the login page. // Logout destroy the session and redirects the user to the login page.
func (c *Controller) Logout(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Logout(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
if err := c.store.RemoveUserSessionByToken(user.ID, ctx.UserSessionToken()); err != nil { if err := c.store.RemoveUserSessionByToken(user.ID, ctx.UserSessionToken()); err != nil {

View file

@ -2,20 +2,20 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/config"
"github.com/miniflux/miniflux/http/cookie"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/cookie" "github.com/miniflux/miniflux/oauth2"
"github.com/miniflux/miniflux/server/core"
"github.com/miniflux/miniflux/server/oauth2"
"github.com/tomasen/realip" "github.com/tomasen/realip"
) )
// OAuth2Redirect redirects the user to the consent page to ask for permission. // OAuth2Redirect redirects the user to the consent page to ask for permission.
func (c *Controller) OAuth2Redirect(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) OAuth2Redirect(ctx *handler.Context, request *handler.Request, response *handler.Response) {
provider := request.StringParam("provider", "") provider := request.StringParam("provider", "")
if provider == "" { if provider == "" {
logger.Error("[OAuth2] Invalid or missing provider: %s", provider) logger.Error("[OAuth2] Invalid or missing provider: %s", provider)
@ -34,7 +34,7 @@ func (c *Controller) OAuth2Redirect(ctx *core.Context, request *core.Request, re
} }
// OAuth2Callback receives the authorization code and create a new session. // OAuth2Callback receives the authorization code and create a new session.
func (c *Controller) OAuth2Callback(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) OAuth2Callback(ctx *handler.Context, request *handler.Request, response *handler.Response) {
provider := request.StringParam("provider", "") provider := request.StringParam("provider", "")
if provider == "" { if provider == "" {
logger.Error("[OAuth2] Invalid or missing provider") logger.Error("[OAuth2] Invalid or missing provider")
@ -136,7 +136,7 @@ func (c *Controller) OAuth2Callback(ctx *core.Context, request *core.Request, re
} }
// OAuth2Unlink unlink an account from the external provider. // OAuth2Unlink unlink an account from the external provider.
func (c *Controller) OAuth2Unlink(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) OAuth2Unlink(ctx *handler.Context, request *handler.Request, response *handler.Response) {
provider := request.StringParam("provider", "") provider := request.StringParam("provider", "")
if provider == "" { if provider == "" {
logger.Info("[OAuth2] Invalid or missing provider") logger.Info("[OAuth2] Invalid or missing provider")

View file

@ -2,15 +2,15 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/core"
) )
// Export generates the OPML file. // Export generates the OPML file.
func (c *Controller) Export(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Export(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
opml, err := c.opmlHandler.Export(user.ID) opml, err := c.opmlHandler.Export(user.ID)
if err != nil { if err != nil {
@ -22,7 +22,7 @@ func (c *Controller) Export(ctx *core.Context, request *core.Request, response *
} }
// Import shows the import form. // Import shows the import form.
func (c *Controller) Import(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Import(ctx *handler.Context, request *handler.Request, response *handler.Response) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
response.HTML().ServerError(err) response.HTML().ServerError(err)
@ -35,7 +35,7 @@ func (c *Controller) Import(ctx *core.Context, request *core.Request, response *
} }
// UploadOPML handles OPML file importation. // UploadOPML handles OPML file importation.
func (c *Controller) UploadOPML(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UploadOPML(ctx *handler.Context, request *handler.Request, response *handler.Response) {
file, fileHeader, err := request.File("file") file, fileHeader, err := request.File("file")
if err != nil { if err != nil {
logger.Error("[Controller:UploadOPML] %v", err) logger.Error("[Controller:UploadOPML] %v", err)

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
const ( const (
nbItemsPerPage = 100 nbItemsPerPage = 100

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package payload package ui
import ( import (
"encoding/json" "encoding/json"
@ -12,8 +12,7 @@ import (
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
) )
// DecodeEntryStatusPayload unserialize JSON request to update entry statuses. func decodeEntryStatusPayload(data io.Reader) (entryIDs []int64, status string, err error) {
func DecodeEntryStatusPayload(data io.Reader) (entryIDs []int64, status string, err error) {
type payload struct { type payload struct {
EntryIDs []int64 `json:"entry_ids"` EntryIDs []int64 `json:"entry_ids"`
Status string `json:"status"` Status string `json:"status"`

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"encoding/base64" "encoding/base64"
@ -12,12 +12,12 @@ import (
"github.com/miniflux/miniflux/crypto" "github.com/miniflux/miniflux/crypto"
"github.com/miniflux/miniflux/http" "github.com/miniflux/miniflux/http"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/core"
) )
// ImageProxy fetch an image from a remote server and sent it back to the browser. // ImageProxy fetch an image from a remote server and sent it back to the browser.
func (c *Controller) ImageProxy(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ImageProxy(ctx *handler.Context, request *handler.Request, response *handler.Response) {
// If we receive a "If-None-Match" header we assume the image in stored in browser cache // If we receive a "If-None-Match" header we assume the image in stored in browser cache
if request.Request().Header.Get("If-None-Match") != "" { if request.Request().Header.Get("If-None-Match") != "" {
response.NotModified() response.NotModified()

View file

@ -2,15 +2,15 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/core"
) )
// ShowSessions shows the list of active user sessions. // ShowSessions shows the list of active user sessions.
func (c *Controller) ShowSessions(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowSessions(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
@ -32,7 +32,7 @@ func (c *Controller) ShowSessions(ctx *core.Context, request *core.Request, resp
} }
// RemoveSession remove a user session. // RemoveSession remove a user session.
func (c *Controller) RemoveSession(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) RemoveSession(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
sessionID, err := request.IntegerParam("sessionID") sessionID, err := request.IntegerParam("sessionID")

View file

@ -2,18 +2,18 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/locale" "github.com/miniflux/miniflux/locale"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/ui/form"
"github.com/miniflux/miniflux/server/ui/form"
) )
// ShowSettings shows the settings page. // ShowSettings shows the settings page.
func (c *Controller) ShowSettings(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowSettings(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
args, err := c.getSettingsFormTemplateArgs(ctx, user, nil) args, err := c.getSettingsFormTemplateArgs(ctx, user, nil)
@ -26,7 +26,7 @@ func (c *Controller) ShowSettings(ctx *core.Context, request *core.Request, resp
} }
// UpdateSettings update the settings. // UpdateSettings update the settings.
func (c *Controller) UpdateSettings(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) UpdateSettings(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
settingsForm := form.NewSettingsForm(request.Request()) settingsForm := form.NewSettingsForm(request.Request())
@ -66,7 +66,7 @@ func (c *Controller) UpdateSettings(ctx *core.Context, request *core.Request, re
response.Redirect(ctx.Route("settings")) response.Redirect(ctx.Route("settings"))
} }
func (c *Controller) getSettingsFormTemplateArgs(ctx *core.Context, user *model.User, settingsForm *form.SettingsForm) (tplParams, error) { func (c *Controller) getSettingsFormTemplateArgs(ctx *handler.Context, user *model.User, settingsForm *form.SettingsForm) (tplParams, error) {
args, err := c.getCommonTemplateArgs(ctx) args, err := c.getCommonTemplateArgs(ctx)
if err != nil { if err != nil {
return args, err return args, err

View file

@ -2,16 +2,16 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/model"
"github.com/miniflux/miniflux/server/core"
) )
// ShowStarredPage renders the page with all starred entries. // ShowStarredPage renders the page with all starred entries.
func (c *Controller) ShowStarredPage(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ShowStarredPage(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
offset := request.QueryIntegerParam("offset", 0) offset := request.QueryIntegerParam("offset", 0)
@ -50,7 +50,7 @@ func (c *Controller) ShowStarredPage(ctx *core.Context, request *core.Request, r
} }
// ToggleBookmark handles Ajax request to toggle bookmark value. // ToggleBookmark handles Ajax request to toggle bookmark value.
func (c *Controller) ToggleBookmark(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) ToggleBookmark(ctx *handler.Context, request *handler.Request, response *handler.Response) {
user := ctx.LoggedUser() user := ctx.LoggedUser()
entryID, err := request.IntegerParam("entryID") entryID, err := request.IntegerParam("entryID")
if err != nil { if err != nil {

View file

@ -2,19 +2,19 @@
// Use of this source code is governed by the Apache 2.0 // Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package controller package ui
import ( import (
"encoding/base64" "encoding/base64"
"time" "time"
"github.com/miniflux/miniflux/http/handler"
"github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/logger"
"github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/ui/static"
"github.com/miniflux/miniflux/server/static"
) )
// Stylesheet renders the CSS. // Stylesheet renders the CSS.
func (c *Controller) Stylesheet(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Stylesheet(ctx *handler.Context, request *handler.Request, response *handler.Response) {
stylesheet := request.StringParam("name", "white") stylesheet := request.StringParam("name", "white")
body := static.Stylesheets["common"] body := static.Stylesheets["common"]
etag := static.StylesheetsChecksums["common"] etag := static.StylesheetsChecksums["common"]
@ -28,12 +28,12 @@ func (c *Controller) Stylesheet(ctx *core.Context, request *core.Request, respon
} }
// Javascript renders application client side code. // Javascript renders application client side code.
func (c *Controller) Javascript(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Javascript(ctx *handler.Context, request *handler.Request, response *handler.Response) {
response.Cache("text/javascript; charset=utf-8", static.JavascriptChecksums["app"], []byte(static.Javascript["app"]), 48*time.Hour) response.Cache("text/javascript; charset=utf-8", static.JavascriptChecksums["app"], []byte(static.Javascript["app"]), 48*time.Hour)
} }
// Favicon renders the application favicon. // Favicon renders the application favicon.
func (c *Controller) Favicon(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) Favicon(ctx *handler.Context, request *handler.Request, response *handler.Response) {
blob, err := base64.StdEncoding.DecodeString(static.Binaries["favicon.ico"]) blob, err := base64.StdEncoding.DecodeString(static.Binaries["favicon.ico"])
if err != nil { if err != nil {
logger.Error("[Controller:Favicon] %v", err) logger.Error("[Controller:Favicon] %v", err)
@ -45,7 +45,7 @@ func (c *Controller) Favicon(ctx *core.Context, request *core.Request, response
} }
// AppIcon returns application icons. // AppIcon returns application icons.
func (c *Controller) AppIcon(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) AppIcon(ctx *handler.Context, request *handler.Request, response *handler.Response) {
filename := request.StringParam("filename", "favicon.png") filename := request.StringParam("filename", "favicon.png")
encodedBlob, found := static.Binaries[filename] encodedBlob, found := static.Binaries[filename]
if !found { if !found {
@ -65,7 +65,7 @@ func (c *Controller) AppIcon(ctx *core.Context, request *core.Request, response
} }
// WebManifest renders web manifest file. // WebManifest renders web manifest file.
func (c *Controller) WebManifest(ctx *core.Context, request *core.Request, response *core.Response) { func (c *Controller) WebManifest(ctx *handler.Context, request *handler.Request, response *handler.Response) {
type webManifestIcon struct { type webManifestIcon struct {
Source string `json:"src"` Source string `json:"src"`
Sizes string `json:"sizes"` Sizes string `json:"sizes"`

View file

@ -1,5 +1,5 @@
// Code generated by go generate; DO NOT EDIT. // Code generated by go generate; DO NOT EDIT.
// 2017-12-22 11:25:01.957187237 -0800 PST m=+0.022154999 // 2018-01-02 21:59:10.082800492 -0800 PST m=+0.010175821
package static package static

View file

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

Before

Width:  |  Height:  |  Size: 847 B

After

Width:  |  Height:  |  Size: 847 B

View file

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Some files were not shown because too many files have changed in this diff Show more