diff --git a/server/api/controller/category.go b/api/category.go similarity index 77% rename from server/api/controller/category.go rename to api/category.go index d7b2922be0503ae1ef8ccadedeefd796c4d9f6ac..67c7e5230d1fef8f0ad5e57a02e660347318cc28 100644 --- a/server/api/controller/category.go +++ b/api/category.go @@ -7,14 +7,13 @@ package api import ( "errors" - "github.com/miniflux/miniflux/server/api/payload" - "github.com/miniflux/miniflux/server/core" + "github.com/miniflux/miniflux/http/handler" ) // 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() - category, err := payload.DecodeCategoryPayload(request.Body()) + category, err := decodeCategoryPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) 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. -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") if err != nil { response.JSON().BadRequest(err) return } - category, err := payload.DecodeCategoryPayload(request.Body()) + category, err := decodeCategoryPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) 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. -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()) if err != nil { 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. -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() categoryID, err := request.IntegerParam("categoryID") if err != nil { diff --git a/server/api/controller/controller.go b/api/controller.go similarity index 100% rename from server/api/controller/controller.go rename to api/controller.go diff --git a/server/api/controller/entry.go b/api/entry.go similarity index 84% rename from server/api/controller/entry.go rename to api/entry.go index 9c86a7a55c0d0684fd5fd18f4d5699d656c9f8fb..4152da8824406e788c7208575b78ea7f1bd973e9 100644 --- a/server/api/controller/entry.go +++ b/api/entry.go @@ -7,13 +7,12 @@ package api import ( "errors" + "github.com/miniflux/miniflux/http/handler" "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. -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() feedID, err := request.IntegerParam("feedID") 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. -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() entryID, err := request.IntegerParam("entryID") 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. -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() feedID, err := request.IntegerParam("feedID") if err != nil { @@ -127,11 +126,11 @@ func (c *Controller) GetFeedEntries(ctx *core.Context, request *core.Request, re 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. -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() status := request.QueryStringParam("status", "") @@ -180,14 +179,14 @@ func (c *Controller) GetEntries(ctx *core.Context, request *core.Request, respon 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. -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() - entryIDs, status, err := payload.DecodeEntryStatusPayload(request.Body()) + entryIDs, status, err := decodeEntryStatusPayload(request.Body()) if err != nil { response.JSON().BadRequest(errors.New("Invalid JSON payload")) 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. -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() entryID, err := request.IntegerParam("entryID") if err != nil { diff --git a/server/api/controller/feed.go b/api/feed.go similarity index 82% rename from server/api/controller/feed.go rename to api/feed.go index fcaeee780ed73cd3b0cd3181bfebe0f3241f081d..c3fc048fc3d8843569547c879404dcc33dc3fdcd 100644 --- a/server/api/controller/feed.go +++ b/api/feed.go @@ -7,14 +7,13 @@ package api import ( "errors" - "github.com/miniflux/miniflux/server/api/payload" - "github.com/miniflux/miniflux/server/core" + "github.com/miniflux/miniflux/http/handler" ) // 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() - feedURL, categoryID, err := payload.DecodeFeedCreationPayload(request.Body()) + feedURL, categoryID, err := decodeFeedCreationPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) 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. -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() feedID, err := request.IntegerParam("feedID") 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. -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() feedID, err := request.IntegerParam("feedID") if err != nil { @@ -85,7 +84,7 @@ func (c *Controller) UpdateFeed(ctx *core.Context, request *core.Request, respon return } - newFeed, err := payload.DecodeFeedModificationPayload(request.Body()) + newFeed, err := decodeFeedModificationPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) 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. -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()) if err != nil { 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. -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() feedID, err := request.IntegerParam("feedID") 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. -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() feedID, err := request.IntegerParam("feedID") if err != nil { diff --git a/server/api/controller/icon.go b/api/icon.go similarity index 77% rename from server/api/controller/icon.go rename to api/icon.go index b8e7a61e7a62483d81cf7937af317d74f7eb5d57..7734dbf84834da178c2b7e514dbb5a466b9898f8 100644 --- a/server/api/controller/icon.go +++ b/api/icon.go @@ -7,12 +7,11 @@ package api import ( "errors" - "github.com/miniflux/miniflux/server/api/payload" - "github.com/miniflux/miniflux/server/core" + "github.com/miniflux/miniflux/http/handler" ) // 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() feedID, err := request.IntegerParam("feedID") if err != nil { @@ -36,7 +35,7 @@ func (c *Controller) FeedIcon(ctx *core.Context, request *core.Request, response return } - response.JSON().Standard(&payload.FeedIcon{ + response.JSON().Standard(&feedIcon{ ID: icon.ID, MimeType: icon.MimeType, Data: icon.DataURL(), diff --git a/server/api/payload/payload.go b/api/payload.go similarity index 67% rename from server/api/payload/payload.go rename to api/payload.go index 25cd65782a533719c5701a67f32eb2d66bcd699a..46c3b044f72b27a650cbb42979e08443fe03d1dc 100644 --- a/server/api/payload/payload.go +++ b/api/payload.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package payload +package api import ( "encoding/json" @@ -12,21 +12,18 @@ import ( "github.com/miniflux/miniflux/model" ) -// FeedIcon represents the feed icon response. -type FeedIcon struct { +type feedIcon struct { ID int64 `json:"id"` MimeType string `json:"mime_type"` Data string `json:"data"` } -// EntriesResponse represents the response sent when fetching entries. -type EntriesResponse struct { +type entriesResponse struct { Total int `json:"total"` 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 decoder := json.NewDecoder(data) @@ -37,8 +34,7 @@ func DecodeUserPayload(data io.Reader) (*model.User, error) { 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 { URL string `json:"url"` } @@ -52,8 +48,7 @@ func DecodeURLPayload(data io.Reader) (string, error) { 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 { EntryIDs []int64 `json:"entry_ids"` Status string `json:"status"` @@ -68,8 +63,7 @@ func DecodeEntryStatusPayload(data io.Reader) ([]int64, string, error) { 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 { FeedURL string `json:"feed_url"` CategoryID int64 `json:"category_id"` @@ -84,8 +78,7 @@ func DecodeFeedCreationPayload(data io.Reader) (string, int64, error) { 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 decoder := json.NewDecoder(data) @@ -96,8 +89,7 @@ func DecodeFeedModificationPayload(data io.Reader) (*model.Feed, error) { 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 decoder := json.NewDecoder(data) diff --git a/server/api/controller/subscription.go b/api/subscription.go similarity index 72% rename from server/api/controller/subscription.go rename to api/subscription.go index aa2a26f9c9ff0e17444b1251cb6d235986388bac..8a8fefff3b9439c571336c76409c9f61d68bb8ff 100644 --- a/server/api/controller/subscription.go +++ b/api/subscription.go @@ -8,14 +8,13 @@ import ( "errors" "fmt" + "github.com/miniflux/miniflux/http/handler" "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. -func (c *Controller) GetSubscriptions(ctx *core.Context, request *core.Request, response *core.Response) { - websiteURL, err := payload.DecodeURLPayload(request.Body()) +func (c *Controller) GetSubscriptions(ctx *handler.Context, request *handler.Request, response *handler.Response) { + websiteURL, err := decodeURLPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) return diff --git a/server/api/controller/user.go b/api/user.go similarity index 81% rename from server/api/controller/user.go rename to api/user.go index a9259081bab5972daabf461cf08b0a433f4c235d..96571b03ced1f3ab3fe4a68dba584a011c8978b2 100644 --- a/server/api/controller/user.go +++ b/api/user.go @@ -7,18 +7,17 @@ package api import ( "errors" - "github.com/miniflux/miniflux/server/api/payload" - "github.com/miniflux/miniflux/server/core" + "github.com/miniflux/miniflux/http/handler" ) // 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() { response.JSON().Forbidden() return } - user, err := payload.DecodeUserPayload(request.Body()) + user, err := decodeUserPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) 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. -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() { response.JSON().Forbidden() return @@ -57,7 +56,7 @@ func (c *Controller) UpdateUser(ctx *core.Context, request *core.Request, respon return } - user, err := payload.DecodeUserPayload(request.Body()) + user, err := decodeUserPayload(request.Body()) if err != nil { response.JSON().BadRequest(err) 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. -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() { response.JSON().Forbidden() 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. -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() { response.JSON().Forbidden() 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. -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() { response.JSON().Forbidden() 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. -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() { response.JSON().Forbidden() return diff --git a/cli/cli.go b/cli/cli.go new file mode 100644 index 0000000000000000000000000000000000000000..67131e60a264a1fafdf5a297c5f348af19b56e3f --- /dev/null +++ b/cli/cli.go @@ -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) +} diff --git a/cli/create_admin.go b/cli/create_admin.go new file mode 100644 index 0000000000000000000000000000000000000000..9af8df3383f3bdafe1422760cb14b0abb2bb54dd --- /dev/null +++ b/cli/create_admin.go @@ -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) + } +} diff --git a/cli/flush_sessions.go b/cli/flush_sessions.go new file mode 100644 index 0000000000000000000000000000000000000000..06a56d0b2fb455bf5fd3e14b8e0b2fb0080172fd --- /dev/null +++ b/cli/flush_sessions.go @@ -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) + } +} diff --git a/cli/info.go b/cli/info.go new file mode 100644 index 0000000000000000000000000000000000000000..2ae1cefea002008139bf822e2fce58918eed1e51 --- /dev/null +++ b/cli/info.go @@ -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()) +} diff --git a/daemon/daemon.go b/daemon/daemon.go new file mode 100644 index 0000000000000000000000000000000000000000..494e03563fcaf9d12e193949b9cf1e9fdab3d3db --- /dev/null +++ b/daemon/daemon.go @@ -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") +} diff --git a/server/routes.go b/daemon/routes.go similarity index 91% rename from server/routes.go rename to daemon/routes.go index e56b8cc81a2c93029599757b5cc6495fdcf11327..0c266f4a141b1ddd9d9b4e2672929a9a37d36232 100644 --- a/server/routes.go +++ b/daemon/routes.go @@ -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 // license that can be found in the LICENSE file. -package server +package daemon import ( "net/http" - "github.com/miniflux/miniflux/scheduler" - + "github.com/miniflux/miniflux/api" "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/reader/feed" "github.com/miniflux/miniflux/reader/opml" - api_controller "github.com/miniflux/miniflux/server/api/controller" - "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/scheduler" "github.com/miniflux/miniflux/storage" + "github.com/miniflux/miniflux/template" + "github.com/miniflux/miniflux/ui" "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() translator := locale.Load() templateEngine := template.NewEngine(cfg, router, translator) - apiController := api_controller.NewController(store, feedHandler) + apiController := api.NewController(store, feedHandler) 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, )) - feverHandler := core.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain( + feverHandler := handler.NewHandler(cfg, store, router, templateEngine, translator, middleware.NewChain( 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.NewSessionMiddleware(cfg, store).Handler, )) diff --git a/server/server.go b/daemon/server.go similarity index 83% rename from server/server.go rename to daemon/server.go index 4627b83c05f91db740ad431810a0c95336344fec..dfdfb79e6b12f00805aa4c1bfd8e88a7255375c2 100644 --- a/server/server.go +++ b/daemon/server.go @@ -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 // license that can be found in the LICENSE file. -package server +package daemon import ( "crypto/tls" "net/http" "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/logger" "github.com/miniflux/miniflux/reader/feed" + "github.com/miniflux/miniflux/scheduler" "github.com/miniflux/miniflux/storage" -) -// NewServer returns a new 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)) -} + "golang.org/x/crypto/acme/autocert" +) -func startServer(cfg *config.Config, handler *mux.Router) *http.Server { +func newServer(cfg *config.Config, store *storage.Storage, pool *scheduler.WorkerPool, feedHandler *feed.Handler) *http.Server { certFile := cfg.Get("CERT_FILE", config.DefaultCertFile) keyFile := cfg.Get("KEY_FILE", config.DefaultKeyFile) 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, IdleTimeout: 60 * time.Second, Addr: cfg.Get("LISTEN_ADDR", config.DefaultListenAddr), - Handler: handler, + Handler: routes(cfg, store, feedHandler, pool), } if certDomain != "" && certCache != "" { diff --git a/server/fever/fever.go b/fever/fever.go similarity index 93% rename from server/fever/fever.go rename to fever/fever.go index 6690b7f8a0dd486c17be66342f10ea4db1c6dc53..54a4416030706eeda31f0b63f00b177f2b036679 100644 --- a/server/fever/fever.go +++ b/fever/fever.go @@ -9,10 +9,10 @@ import ( "strings" "time" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/integration" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/storage" ) @@ -129,7 +129,7 @@ type Controller struct { } // 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 { case request.HasQueryParam("groups"): 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. */ -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() 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. */ -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() logger.Debug("[Fever] Fetching feeds for userID=%d", userID) @@ -277,7 +277,7 @@ A PHP/HTML example: 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() 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) */ -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 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: 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() 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) */ -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() 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 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() 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 before=? where ? is replaced with the Unix timestamp of the the local client’s 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() 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 before=? where ? is replaced with the Unix timestamp of the the local client’s 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() logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID) diff --git a/server/ui/filter/image_proxy_filter.go b/filter/image_proxy_filter.go similarity index 95% rename from server/ui/filter/image_proxy_filter.go rename to filter/image_proxy_filter.go index 12c9da635aa1c8d94caf9c0212f491bae439af59..ef6d39733b09f304a3dc35264942ba6885fd5612 100644 --- a/server/ui/filter/image_proxy_filter.go +++ b/filter/image_proxy_filter.go @@ -8,7 +8,7 @@ import ( "encoding/base64" "strings" - "github.com/miniflux/miniflux/server/route" + "github.com/miniflux/miniflux/http/route" "github.com/miniflux/miniflux/url" "github.com/PuerkitoBio/goquery" diff --git a/server/ui/filter/image_proxy_filter_test.go b/filter/image_proxy_filter_test.go similarity index 100% rename from server/ui/filter/image_proxy_filter_test.go rename to filter/image_proxy_filter_test.go diff --git a/generate.go b/generate.go index cc3bc5e2253a7122464dd7941679dd1421599c66..266a9fd600986a8a06d4c89abab4213dc1f6828d 100644 --- a/generate.go +++ b/generate.go @@ -111,10 +111,10 @@ func generateFile(serializer, pkg, mapName, pattern, output string) { func main() { generateFile("none", "sql", "SqlMap", "sql/*.sql", "sql/sql.go") - generateFile("base64", "static", "Binaries", "server/static/bin/*", "server/static/bin.go") - generateFile("css", "static", "Stylesheets", "server/static/css/*.css", "server/static/css.go") - generateFile("js", "static", "Javascript", "server/static/js/*.js", "server/static/js.go") - generateFile("none", "template", "templateViewsMap", "server/template/html/*.html", "server/template/views.go") - generateFile("none", "template", "templateCommonMap", "server/template/html/common/*.html", "server/template/common.go") + generateFile("base64", "static", "Binaries", "ui/static/bin/*", "ui/static/bin.go") + generateFile("css", "static", "Stylesheets", "ui/static/css/*.css", "ui/static/css.go") + generateFile("js", "static", "Javascript", "ui/static/js/*.js", "ui/static/js.go") + generateFile("none", "template", "templateViewsMap", "template/html/*.html", "template/views.go") + generateFile("none", "template", "templateCommonMap", "template/html/common/*.html", "template/common.go") generateFile("none", "locale", "translations", "locale/translations/*.json", "locale/translations.go") } diff --git a/server/cookie/cookie.go b/http/cookie/cookie.go similarity index 100% rename from server/cookie/cookie.go rename to http/cookie/cookie.go diff --git a/server/core/context.go b/http/handler/context.go similarity index 92% rename from server/core/context.go rename to http/handler/context.go index 8145b4718cbb72594a9a540a3488738ad54a99d6..a04a8166d49c85f30da4ab04e14cb1caec8457f4 100644 --- a/server/core/context.go +++ b/http/handler/context.go @@ -2,17 +2,17 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "net/http" "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/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/middleware" - "github.com/miniflux/miniflux/server/route" "github.com/miniflux/miniflux/storage" "github.com/gorilla/mux" @@ -155,6 +155,6 @@ func (c *Context) Route(name string, args ...interface{}) string { } // NewContext creates a new Context. -func NewContext(w http.ResponseWriter, 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} +func NewContext(r *http.Request, store *storage.Storage, router *mux.Router, translator *locale.Translator) *Context { + return &Context{request: r, store: store, router: router, translator: translator} } diff --git a/server/core/handler.go b/http/handler/handler.go similarity index 81% rename from server/core/handler.go rename to http/handler/handler.go index e6aca98ac0e29e97a3ad6df92ce479bda98247a9..3dd1d1b11982734cf5d70d5f061edba0086586e9 100644 --- a/server/core/handler.go +++ b/http/handler/handler.go @@ -2,26 +2,26 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "net/http" "time" "github.com/miniflux/miniflux/config" + "github.com/miniflux/miniflux/http/middleware" "github.com/miniflux/miniflux/locale" "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/template" "github.com/miniflux/miniflux/timer" "github.com/gorilla/mux" "github.com/tomasen/realip" ) -// HandlerFunc is an application HTTP handler. -type HandlerFunc func(ctx *Context, request *Request, response *Response) +// ControllerFunc is an application HTTP handler. +type ControllerFunc func(ctx *Context, request *Request, response *Response) // Handler manages HTTP handlers and middlewares. type Handler struct { @@ -34,7 +34,7 @@ type Handler struct { } // 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) { defer timer.ExecutionTime(time.Now(), 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 } - ctx := NewContext(w, r, h.store, h.router, h.translator) - request := NewRequest(w, r) + ctx := NewContext(r, h.store, h.router, h.translator) + request := NewRequest(r) response := NewResponse(w, r, h.template) if ctx.IsAuthenticated() { diff --git a/server/core/html_response.go b/http/handler/html_response.go similarity index 96% rename from server/core/html_response.go rename to http/handler/html_response.go index a1941631a7e735fb176df04ff3f4f9f33744cef5..26e52708f8687b220e56d3e8ff8246d1a93ed82e 100644 --- a/server/core/html_response.go +++ b/http/handler/html_response.go @@ -2,13 +2,13 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "net/http" "github.com/miniflux/miniflux/logger" - "github.com/miniflux/miniflux/server/template" + "github.com/miniflux/miniflux/template" ) // HTMLResponse handles HTML responses. diff --git a/server/core/json_response.go b/http/handler/json_response.go similarity index 99% rename from server/core/json_response.go rename to http/handler/json_response.go index 8ee0b7f10d462cb6fbfd4e28c209c27cb9ff587c..a79268c9c667e704f5df03246315d25335156637 100644 --- a/server/core/json_response.go +++ b/http/handler/json_response.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "encoding/json" diff --git a/server/core/request.go b/http/handler/request.go similarity index 93% rename from server/core/request.go rename to http/handler/request.go index f3a365231f1318c7b0d6f3354e9a0c2ae06dd673..7289a70f3f143c7047e5a1e30ae9feabc6748141 100644 --- a/server/core/request.go +++ b/http/handler/request.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "fmt" @@ -17,7 +17,6 @@ import ( // Request is a thin wrapper around "http.Request". type Request struct { - writer http.ResponseWriter request *http.Request } @@ -119,7 +118,7 @@ func (r *Request) HasQueryParam(param string) bool { return ok } -// NewRequest returns a new Request struct. -func NewRequest(w http.ResponseWriter, r *http.Request) *Request { - return &Request{writer: w, request: r} +// NewRequest returns a new Request. +func NewRequest(r *http.Request) *Request { + return &Request{r} } diff --git a/server/core/response.go b/http/handler/response.go similarity index 97% rename from server/core/response.go rename to http/handler/response.go index f3fc7a104159b5d1c2f095e00281b56e2fe35757..34980a3633558cd6e5bf3197574a2f53021ae25a 100644 --- a/server/core/response.go +++ b/http/handler/response.go @@ -2,13 +2,13 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "net/http" "time" - "github.com/miniflux/miniflux/server/template" + "github.com/miniflux/miniflux/template" ) // Response handles HTTP responses. diff --git a/server/core/xml_response.go b/http/handler/xml_response.go similarity index 97% rename from server/core/xml_response.go rename to http/handler/xml_response.go index e9a2d3fec8283b2ea1894317b17834c683179baa..b5a24cab5cc5bc4c3b3597c010a0bfe162ba5743 100644 --- a/server/core/xml_response.go +++ b/http/handler/xml_response.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package core +package handler import ( "fmt" diff --git a/server/middleware/basic_auth.go b/http/middleware/basic_auth.go similarity index 100% rename from server/middleware/basic_auth.go rename to http/middleware/basic_auth.go diff --git a/server/middleware/context_keys.go b/http/middleware/context_keys.go similarity index 100% rename from server/middleware/context_keys.go rename to http/middleware/context_keys.go diff --git a/server/middleware/fever.go b/http/middleware/fever.go similarity index 100% rename from server/middleware/fever.go rename to http/middleware/fever.go diff --git a/server/middleware/middleware.go b/http/middleware/middleware.go similarity index 100% rename from server/middleware/middleware.go rename to http/middleware/middleware.go diff --git a/server/middleware/session.go b/http/middleware/session.go similarity index 98% rename from server/middleware/session.go rename to http/middleware/session.go index ad02bb244ab2eb325b805fcdf61ce4a5783f4848..a0e9fbd8db3ea2b2e5f63cfe882b70051c5df9e1 100644 --- a/server/middleware/session.go +++ b/http/middleware/session.go @@ -9,9 +9,9 @@ import ( "net/http" "github.com/miniflux/miniflux/config" + "github.com/miniflux/miniflux/http/cookie" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/cookie" "github.com/miniflux/miniflux/storage" ) diff --git a/server/middleware/user_session.go b/http/middleware/user_session.go similarity index 96% rename from server/middleware/user_session.go rename to http/middleware/user_session.go index 3d1dae614dd67d216a59e2d49f26c3d8f7d74b31..d67445f0ac11be58253785184c70e28230d1d7ee 100644 --- a/server/middleware/user_session.go +++ b/http/middleware/user_session.go @@ -8,10 +8,10 @@ import ( "context" "net/http" + "github.com/miniflux/miniflux/http/cookie" + "github.com/miniflux/miniflux/http/route" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/cookie" - "github.com/miniflux/miniflux/server/route" "github.com/miniflux/miniflux/storage" "github.com/gorilla/mux" diff --git a/server/route/route.go b/http/route/route.go similarity index 100% rename from server/route/route.go rename to http/route/route.go diff --git a/locale/translations.go b/locale/translations.go index 132ed314e5ecd07ebc6f99f0c197197826cf6155..ac073c8ec985e7f76eaec2a4ceda56af0c79063a 100644 --- a/locale/translations.go +++ b/locale/translations.go @@ -1,5 +1,5 @@ // 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 diff --git a/main.go b/main.go index a252c61005efc38ec2640644159007aa749e03fb..79dcf2708178be932a8dc3e335c1e84f389fce6e 100644 --- a/main.go +++ b/main.go @@ -6,140 +6,18 @@ package main //go:generate go run generate.go //go:generate gofmt -s -w sql/sql.go -//go:generate gofmt -s -w server/static/css.go -//go:generate gofmt -s -w server/static/bin.go -//go:generate gofmt -s -w server/static/js.go -//go:generate gofmt -s -w server/template/views.go -//go:generate gofmt -s -w server/template/common.go +//go:generate gofmt -s -w ui/static/css.go +//go:generate gofmt -s -w ui/static/bin.go +//go:generate gofmt -s -w ui/static/js.go +//go:generate gofmt -s -w template/views.go +//go:generate gofmt -s -w template/common.go //go:generate gofmt -s -w locale/translations.go 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" - "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() { - 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 { - 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) + cli.Parse() } diff --git a/server/oauth2/google.go b/oauth2/google.go similarity index 100% rename from server/oauth2/google.go rename to oauth2/google.go diff --git a/server/oauth2/manager.go b/oauth2/manager.go similarity index 100% rename from server/oauth2/manager.go rename to oauth2/manager.go diff --git a/server/oauth2/profile.go b/oauth2/profile.go similarity index 100% rename from server/oauth2/profile.go rename to oauth2/profile.go diff --git a/server/oauth2/provider.go b/oauth2/provider.go similarity index 100% rename from server/oauth2/provider.go rename to oauth2/provider.go diff --git a/sql/sql.go b/sql/sql.go index f098915cc5673f80c714bad72cb9da6d38e7182b..36f344e98a5af497cd916df3b1bc327e4edf7369 100644 --- a/sql/sql.go +++ b/sql/sql.go @@ -1,5 +1,5 @@ // 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 diff --git a/server/template/common.go b/template/common.go similarity index 99% rename from server/template/common.go rename to template/common.go index f0a481d547fa6d52ba294fd147509ce6711ac688..7ec578fd15b43ec9295407d967983c10951ad975 100644 --- a/server/template/common.go +++ b/template/common.go @@ -1,5 +1,5 @@ // 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 diff --git a/server/template/html/about.html b/template/html/about.html similarity index 100% rename from server/template/html/about.html rename to template/html/about.html diff --git a/server/template/html/add_subscription.html b/template/html/add_subscription.html similarity index 100% rename from server/template/html/add_subscription.html rename to template/html/add_subscription.html diff --git a/server/template/html/categories.html b/template/html/categories.html similarity index 100% rename from server/template/html/categories.html rename to template/html/categories.html diff --git a/server/template/html/category_entries.html b/template/html/category_entries.html similarity index 100% rename from server/template/html/category_entries.html rename to template/html/category_entries.html diff --git a/server/template/html/choose_subscription.html b/template/html/choose_subscription.html similarity index 100% rename from server/template/html/choose_subscription.html rename to template/html/choose_subscription.html diff --git a/server/template/html/common/entry_pagination.html b/template/html/common/entry_pagination.html similarity index 100% rename from server/template/html/common/entry_pagination.html rename to template/html/common/entry_pagination.html diff --git a/server/template/html/common/layout.html b/template/html/common/layout.html similarity index 100% rename from server/template/html/common/layout.html rename to template/html/common/layout.html diff --git a/server/template/html/common/pagination.html b/template/html/common/pagination.html similarity index 100% rename from server/template/html/common/pagination.html rename to template/html/common/pagination.html diff --git a/server/template/html/create_category.html b/template/html/create_category.html similarity index 100% rename from server/template/html/create_category.html rename to template/html/create_category.html diff --git a/server/template/html/create_user.html b/template/html/create_user.html similarity index 100% rename from server/template/html/create_user.html rename to template/html/create_user.html diff --git a/server/template/html/edit_category.html b/template/html/edit_category.html similarity index 100% rename from server/template/html/edit_category.html rename to template/html/edit_category.html diff --git a/server/template/html/edit_feed.html b/template/html/edit_feed.html similarity index 100% rename from server/template/html/edit_feed.html rename to template/html/edit_feed.html diff --git a/server/template/html/edit_user.html b/template/html/edit_user.html similarity index 100% rename from server/template/html/edit_user.html rename to template/html/edit_user.html diff --git a/server/template/html/entry.html b/template/html/entry.html similarity index 100% rename from server/template/html/entry.html rename to template/html/entry.html diff --git a/server/template/html/feed_entries.html b/template/html/feed_entries.html similarity index 100% rename from server/template/html/feed_entries.html rename to template/html/feed_entries.html diff --git a/server/template/html/feeds.html b/template/html/feeds.html similarity index 100% rename from server/template/html/feeds.html rename to template/html/feeds.html diff --git a/server/template/html/history.html b/template/html/history.html similarity index 100% rename from server/template/html/history.html rename to template/html/history.html diff --git a/server/template/html/import.html b/template/html/import.html similarity index 100% rename from server/template/html/import.html rename to template/html/import.html diff --git a/server/template/html/integrations.html b/template/html/integrations.html similarity index 100% rename from server/template/html/integrations.html rename to template/html/integrations.html diff --git a/server/template/html/login.html b/template/html/login.html similarity index 100% rename from server/template/html/login.html rename to template/html/login.html diff --git a/server/template/html/sessions.html b/template/html/sessions.html similarity index 100% rename from server/template/html/sessions.html rename to template/html/sessions.html diff --git a/server/template/html/settings.html b/template/html/settings.html similarity index 100% rename from server/template/html/settings.html rename to template/html/settings.html diff --git a/server/template/html/starred.html b/template/html/starred.html similarity index 100% rename from server/template/html/starred.html rename to template/html/starred.html diff --git a/server/template/html/unread.html b/template/html/unread.html similarity index 100% rename from server/template/html/unread.html rename to template/html/unread.html diff --git a/server/template/html/users.html b/template/html/users.html similarity index 100% rename from server/template/html/users.html rename to template/html/users.html diff --git a/server/template/template.go b/template/template.go similarity index 97% rename from server/template/template.go rename to template/template.go index a87d097ce2f311832a0c0feefc68a14317a472e0..60d4d854c561fccf021c2956eaffb0fe5007925b 100644 --- a/server/template/template.go +++ b/template/template.go @@ -15,10 +15,10 @@ import ( "github.com/miniflux/miniflux/config" "github.com/miniflux/miniflux/duration" "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/logger" - "github.com/miniflux/miniflux/server/route" - "github.com/miniflux/miniflux/server/ui/filter" "github.com/miniflux/miniflux/url" "github.com/gorilla/mux" diff --git a/server/template/views.go b/template/views.go similarity index 99% rename from server/template/views.go rename to template/views.go index 4eac6e44c269f3d1d81e75fc957df07c6750cfb6..8bc5c79259deb71c6dccbf75d0c7bbdd62a84f14 100644 --- a/server/template/views.go +++ b/template/views.go @@ -1,5 +1,5 @@ // 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 diff --git a/server/ui/controller/about.go b/ui/about.go similarity index 75% rename from server/ui/controller/about.go rename to ui/about.go index d6bfc279b7a452aa4bd68141e2ecabb0cbc6ed0f..91713d8f4809af89df4bd5f0c92ad02e8f2be75e 100644 --- a/server/ui/controller/about.go +++ b/ui/about.go @@ -2,15 +2,15 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( - "github.com/miniflux/miniflux/server/core" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/version" ) // 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) if err != nil { response.HTML().ServerError(err) diff --git a/server/ui/controller/category.go b/ui/category.go similarity index 82% rename from server/ui/controller/category.go rename to ui/category.go index cf378c6d37413f46cc2be399b7bc78db705724a2..ba2d565a5894198b5dff5351bd6621a1bc61b11e 100644 --- a/server/ui/controller/category.go +++ b/ui/category.go @@ -2,19 +2,19 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "errors" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/ui/form" ) // 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) if err != nil { 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. -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() 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. -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) if err != nil { 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. -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() args, err := c.getCommonTemplateArgs(ctx) 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. -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() 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. -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() 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. -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() 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")) } -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") if err != nil { response.HTML().BadRequest(err) @@ -237,7 +237,7 @@ func (c *Controller) getCategoryFromURL(ctx *core.Context, request *core.Request 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) if err != nil { return nil, err diff --git a/server/ui/controller/controller.go b/ui/controller.go similarity index 91% rename from server/ui/controller/controller.go rename to ui/controller.go index 8555c7b887eba1f5fab9db7310de8602b91cdf2f..44e0b2909c8bb4908430ba231d8b08fbc1f07a6b 100644 --- a/server/ui/controller/controller.go +++ b/ui/controller.go @@ -2,15 +2,15 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "github.com/miniflux/miniflux/config" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/reader/feed" "github.com/miniflux/miniflux/reader/opml" "github.com/miniflux/miniflux/scheduler" - "github.com/miniflux/miniflux/server/core" "github.com/miniflux/miniflux/storage" ) @@ -33,7 +33,7 @@ type Controller struct { opmlHandler *opml.Handler } -func (c *Controller) getCommonTemplateArgs(ctx *core.Context) (tplParams, error) { +func (c *Controller) getCommonTemplateArgs(ctx *handler.Context) (tplParams, error) { user := ctx.LoggedUser() builder := c.store.NewEntryQueryBuilder(user.ID) builder.WithStatus(model.EntryStatusUnread) diff --git a/server/ui/controller/entry.go b/ui/entry.go similarity index 91% rename from server/ui/controller/entry.go rename to ui/entry.go index ca9f44af1dcce0a43b735b03c3d216afea1d5e0f..a67fa6837f1705fc69100ea1e873d2edd003c0c3 100644 --- a/server/ui/controller/entry.go +++ b/ui/entry.go @@ -2,24 +2,22 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "errors" - "github.com/miniflux/miniflux/logger" - "github.com/miniflux/miniflux/reader/sanitizer" - + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/integration" + "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" + "github.com/miniflux/miniflux/reader/sanitizer" "github.com/miniflux/miniflux/reader/scraper" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/payload" "github.com/miniflux/miniflux/storage" ) // 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") if err != nil { 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. -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") if err != nil { 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. -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() 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. -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() 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. -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() 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. -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() 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. -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() 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. -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() - entryIDs, status, err := payload.DecodeEntryStatusPayload(request.Body()) + entryIDs, status, err := decodeEntryStatusPayload(request.Body()) if err != nil { logger.Error("[Controller:UpdateEntryStatus] %v", err) response.JSON().BadRequest(nil) diff --git a/server/ui/controller/feed.go b/ui/feed.go similarity index 81% rename from server/ui/controller/feed.go rename to ui/feed.go index 7dfc56e57209ce2ec1dc12d3de7108d97413580d..e524edf902aed474faa13d47072c9c72131270b0 100644 --- a/server/ui/controller/feed.go +++ b/ui/feed.go @@ -2,19 +2,19 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "errors" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/ui/form" ) // 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() jobs, err := c.store.NewUserBatch(user.ID, c.store.CountFeeds(user.ID)) 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. -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() 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. -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() 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. -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() 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. -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() 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. -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") if err != nil { 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. -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") if err != nil { 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)) } -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") if err != nil { response.HTML().BadRequest(err) @@ -204,7 +204,7 @@ func (c *Controller) getFeedFromURL(request *core.Request, response *core.Respon 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) if err != nil { return nil, err diff --git a/server/ui/form/auth.go b/ui/form/auth.go similarity index 100% rename from server/ui/form/auth.go rename to ui/form/auth.go diff --git a/server/ui/form/category.go b/ui/form/category.go similarity index 100% rename from server/ui/form/category.go rename to ui/form/category.go diff --git a/server/ui/form/feed.go b/ui/form/feed.go similarity index 100% rename from server/ui/form/feed.go rename to ui/form/feed.go diff --git a/server/ui/form/integration.go b/ui/form/integration.go similarity index 100% rename from server/ui/form/integration.go rename to ui/form/integration.go diff --git a/server/ui/form/settings.go b/ui/form/settings.go similarity index 100% rename from server/ui/form/settings.go rename to ui/form/settings.go diff --git a/server/ui/form/subscription.go b/ui/form/subscription.go similarity index 100% rename from server/ui/form/subscription.go rename to ui/form/subscription.go diff --git a/server/ui/form/user.go b/ui/form/user.go similarity index 100% rename from server/ui/form/user.go rename to ui/form/user.go diff --git a/server/ui/controller/history.go b/ui/history.go similarity index 82% rename from server/ui/controller/history.go rename to ui/history.go index 7347bacc41bf145c5ee76361970dbdcc15b1f598..63d0ca7884afc6e58c916b72f1a44dc9b72c90e8 100644 --- a/server/ui/controller/history.go +++ b/ui/history.go @@ -2,15 +2,15 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" ) // 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() 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". -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() err := c.store.FlushHistory(user.ID) diff --git a/server/ui/controller/icon.go b/ui/icon.go similarity index 77% rename from server/ui/controller/icon.go rename to ui/icon.go index f5ff1db3af962bfcb7baff4d0343cbc8367a2574..4c445f0426ee2f4de8b72f2543b6dcf7ad2009ee 100644 --- a/server/ui/controller/icon.go +++ b/ui/icon.go @@ -2,16 +2,16 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "time" - "github.com/miniflux/miniflux/server/core" + "github.com/miniflux/miniflux/http/handler" ) // 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") if err != nil { response.HTML().BadRequest(err) diff --git a/server/ui/controller/integrations.go b/ui/integrations.go similarity index 88% rename from server/ui/controller/integrations.go rename to ui/integrations.go index 9ff4baa44424d16c72de786eac7df57d3cf470ed..b30185100e58e93de52684370af98adc96fa7894 100644 --- a/server/ui/controller/integrations.go +++ b/ui/integrations.go @@ -2,18 +2,18 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "crypto/md5" "fmt" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/http/handler" + "github.com/miniflux/miniflux/ui/form" ) // 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() integration, err := c.store.Integration(user.ID) if err != nil { @@ -51,7 +51,7 @@ func (c *Controller) ShowIntegrations(ctx *core.Context, request *core.Request, } // 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() integration, err := c.store.Integration(user.ID) if err != nil { diff --git a/server/ui/controller/login.go b/ui/login.go similarity index 79% rename from server/ui/controller/login.go rename to ui/login.go index ef99c82422c4755eb840c2b19839e5ed4775241b..daaac58c090a9afc1b15b9420aaf194d8f8c4c08 100644 --- a/server/ui/controller/login.go +++ b/ui/login.go @@ -2,19 +2,19 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/cookie" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" - "github.com/miniflux/miniflux/server/cookie" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/ui/form" "github.com/tomasen/realip" ) // 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() { response.Redirect(ctx.Route("unread")) 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. -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()) tplParams := tplParams{ "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. -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() if err := c.store.RemoveUserSessionByToken(user.ID, ctx.UserSessionToken()); err != nil { diff --git a/server/ui/controller/oauth2.go b/ui/oauth2.go similarity index 90% rename from server/ui/controller/oauth2.go rename to ui/oauth2.go index 2aaa5d7da1540e98a778020bd2c6d4eca03e948d..12ca57239f8697f5fbd336a948052b934b3648c9 100644 --- a/server/ui/controller/oauth2.go +++ b/ui/oauth2.go @@ -2,20 +2,20 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "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/model" - "github.com/miniflux/miniflux/server/cookie" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/oauth2" + "github.com/miniflux/miniflux/oauth2" "github.com/tomasen/realip" ) // 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", "") if 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. -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", "") if 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. -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", "") if provider == "" { logger.Info("[OAuth2] Invalid or missing provider") diff --git a/server/ui/controller/opml.go b/ui/opml.go similarity index 78% rename from server/ui/controller/opml.go rename to ui/opml.go index d8016779f9d666997d46878501af37cbf6d55097..80925fb52d07b54663355d792bffbd9a48ac20b8 100644 --- a/server/ui/controller/opml.go +++ b/ui/opml.go @@ -2,15 +2,15 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" - "github.com/miniflux/miniflux/server/core" ) // 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() opml, err := c.opmlHandler.Export(user.ID) if err != nil { @@ -22,7 +22,7 @@ func (c *Controller) Export(ctx *core.Context, request *core.Request, response * } // 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) if err != nil { response.HTML().ServerError(err) @@ -35,7 +35,7 @@ func (c *Controller) Import(ctx *core.Context, request *core.Request, response * } // 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") if err != nil { logger.Error("[Controller:UploadOPML] %v", err) diff --git a/server/ui/controller/pagination.go b/ui/pagination.go similarity index 97% rename from server/ui/controller/pagination.go rename to ui/pagination.go index 1d61f74f13abbb2cc75f99ad92964bfd6e7f02c9..751ba8abc5c12088dbce8e1b826a8ec9ac899c21 100644 --- a/server/ui/controller/pagination.go +++ b/ui/pagination.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui const ( nbItemsPerPage = 100 diff --git a/server/ui/payload/payload.go b/ui/payload.go similarity index 80% rename from server/ui/payload/payload.go rename to ui/payload.go index d91e34a85c6dbe06905bc1a1ce26a8d75231a123..28418288a7e259b5849d1c2b25766aebbce8cd9d 100644 --- a/server/ui/payload/payload.go +++ b/ui/payload.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package payload +package ui import ( "encoding/json" @@ -12,8 +12,7 @@ import ( "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 { EntryIDs []int64 `json:"entry_ids"` Status string `json:"status"` diff --git a/server/ui/controller/proxy.go b/ui/proxy.go similarity index 88% rename from server/ui/controller/proxy.go rename to ui/proxy.go index 6ee52b88757d3b87f9faf42503b62c958bb049ca..5237d006e1e10eb84a507da02edd38c4c944a46a 100644 --- a/server/ui/controller/proxy.go +++ b/ui/proxy.go @@ -2,7 +2,7 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "encoding/base64" @@ -12,12 +12,12 @@ import ( "github.com/miniflux/miniflux/crypto" "github.com/miniflux/miniflux/http" + "github.com/miniflux/miniflux/http/handler" "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. -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 request.Request().Header.Get("If-None-Match") != "" { response.NotModified() diff --git a/server/ui/controller/session.go b/ui/session.go similarity index 79% rename from server/ui/controller/session.go rename to ui/session.go index 05cb29edb66f90e612c03f08f845f6eafa63b512..4134ac61a33db5ba0cdb67001f29c5a97ac724a8 100644 --- a/server/ui/controller/session.go +++ b/ui/session.go @@ -2,15 +2,15 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" - "github.com/miniflux/miniflux/server/core" ) // 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() args, err := c.getCommonTemplateArgs(ctx) if err != nil { @@ -32,7 +32,7 @@ func (c *Controller) ShowSessions(ctx *core.Context, request *core.Request, resp } // 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() sessionID, err := request.IntegerParam("sessionID") diff --git a/server/ui/controller/settings.go b/ui/settings.go similarity index 82% rename from server/ui/controller/settings.go rename to ui/settings.go index feba8936c5bb835fcf5580ef5ad86652d1df7afa..725aa619873aaecb1bd771a4328f5151a39507ac 100644 --- a/server/ui/controller/settings.go +++ b/ui/settings.go @@ -2,18 +2,18 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/locale" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/ui/form" ) // 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() 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. -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() 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")) } -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) if err != nil { return args, err diff --git a/server/ui/controller/starred.go b/ui/starred.go similarity index 84% rename from server/ui/controller/starred.go rename to ui/starred.go index e9da241a25705544eace1ebb801077dcb5831f20..738628f97f865e7c4c3c59428fbef5438d16d785 100644 --- a/server/ui/controller/starred.go +++ b/ui/starred.go @@ -2,16 +2,16 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" ) // 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() 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. -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() entryID, err := request.IntegerParam("entryID") if err != nil { diff --git a/server/ui/controller/static.go b/ui/static.go similarity index 80% rename from server/ui/controller/static.go rename to ui/static.go index 7cf7a35d0ca0e2d03f06f39f17cada9d124f62f6..266d9e691ee4e70a83e45c93c59f07e6a1be41c5 100644 --- a/server/ui/controller/static.go +++ b/ui/static.go @@ -2,19 +2,19 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "encoding/base64" "time" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/static" + "github.com/miniflux/miniflux/ui/static" ) // 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") body := static.Stylesheets["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. -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) } // 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"]) if err != nil { 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. -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") encodedBlob, found := static.Binaries[filename] if !found { @@ -65,7 +65,7 @@ func (c *Controller) AppIcon(ctx *core.Context, request *core.Request, response } // 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 { Source string `json:"src"` Sizes string `json:"sizes"` diff --git a/server/static/bin.go b/ui/static/bin.go similarity index 99% rename from server/static/bin.go rename to ui/static/bin.go index b464f3078fcf13825dce0f8f76046b3ddea5837f..11a953b31cb7bb1dc196e63ef2142170a5bfc2fa 100644 --- a/server/static/bin.go +++ b/ui/static/bin.go @@ -1,5 +1,5 @@ // 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 diff --git a/server/static/bin/favicon.ico b/ui/static/bin/favicon.ico similarity index 100% rename from server/static/bin/favicon.ico rename to ui/static/bin/favicon.ico diff --git a/server/static/bin/favicon.png b/ui/static/bin/favicon.png similarity index 100% rename from server/static/bin/favicon.png rename to ui/static/bin/favicon.png diff --git a/server/static/bin/touch-icon-ipad-retina.png b/ui/static/bin/touch-icon-ipad-retina.png similarity index 100% rename from server/static/bin/touch-icon-ipad-retina.png rename to ui/static/bin/touch-icon-ipad-retina.png diff --git a/server/static/bin/touch-icon-ipad.png b/ui/static/bin/touch-icon-ipad.png similarity index 100% rename from server/static/bin/touch-icon-ipad.png rename to ui/static/bin/touch-icon-ipad.png diff --git a/server/static/bin/touch-icon-iphone-retina.png b/ui/static/bin/touch-icon-iphone-retina.png similarity index 100% rename from server/static/bin/touch-icon-iphone-retina.png rename to ui/static/bin/touch-icon-iphone-retina.png diff --git a/server/static/bin/touch-icon-iphone.png b/ui/static/bin/touch-icon-iphone.png similarity index 100% rename from server/static/bin/touch-icon-iphone.png rename to ui/static/bin/touch-icon-iphone.png diff --git a/server/static/css.go b/ui/static/css.go similarity index 99% rename from server/static/css.go rename to ui/static/css.go index e7f678ff3024957e9b0a2931e5f0e3d93835d9f3..262b85352e88ffae58339cc17a078cf5c2bb606c 100644 --- a/server/static/css.go +++ b/ui/static/css.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// 2017-12-28 18:55:07.393604426 -0800 PST m=+0.020325012 +// 2018-01-02 21:59:10.086272492 -0800 PST m=+0.013647821 package static diff --git a/server/static/css/black.css b/ui/static/css/black.css similarity index 100% rename from server/static/css/black.css rename to ui/static/css/black.css diff --git a/server/static/css/common.css b/ui/static/css/common.css similarity index 100% rename from server/static/css/common.css rename to ui/static/css/common.css diff --git a/server/static/js.go b/ui/static/js.go similarity index 99% rename from server/static/js.go rename to ui/static/js.go index ce9d070f9d68a7bcdd9eb123c68d887d72944361..04fc9458a24a2468229b71069440ff68f0dc964e 100644 --- a/server/static/js.go +++ b/ui/static/js.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// 2017-12-28 18:55:07.395760341 -0800 PST m=+0.022480927 +// 2018-01-02 21:59:10.089270078 -0800 PST m=+0.016645407 package static diff --git a/server/static/js/app.js b/ui/static/js/app.js similarity index 100% rename from server/static/js/app.js rename to ui/static/js/app.js diff --git a/server/ui/controller/subscription.go b/ui/subscription.go similarity index 84% rename from server/ui/controller/subscription.go rename to ui/subscription.go index d243f9a9d2bd96c5d501a3e1633a772f7b8bd239..ad323ada98082cbd19ffc8c69edabfe18507e57f 100644 --- a/server/ui/controller/subscription.go +++ b/ui/subscription.go @@ -2,18 +2,18 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" "github.com/miniflux/miniflux/reader/subscription" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/ui/form" ) // Bookmarklet prefill the form to add a subscription from the URL provided by the bookmarklet. -func (c *Controller) Bookmarklet(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) Bookmarklet(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() args, err := c.getSubscriptionFormTemplateArgs(ctx, user) if err != nil { @@ -28,7 +28,7 @@ func (c *Controller) Bookmarklet(ctx *core.Context, request *core.Request, respo } // AddSubscription shows the form to add a new feed. -func (c *Controller) AddSubscription(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) AddSubscription(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() args, err := c.getSubscriptionFormTemplateArgs(ctx, user) @@ -41,7 +41,7 @@ func (c *Controller) AddSubscription(ctx *core.Context, request *core.Request, r } // SubmitSubscription try to find a feed from the URL provided by the user. -func (c *Controller) SubmitSubscription(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) SubmitSubscription(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() args, err := c.getSubscriptionFormTemplateArgs(ctx, user) @@ -98,7 +98,7 @@ func (c *Controller) SubmitSubscription(ctx *core.Context, request *core.Request } // ChooseSubscription shows a page to choose a subscription. -func (c *Controller) ChooseSubscription(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) ChooseSubscription(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() args, err := c.getSubscriptionFormTemplateArgs(ctx, user) @@ -128,7 +128,7 @@ func (c *Controller) ChooseSubscription(ctx *core.Context, request *core.Request response.Redirect(ctx.Route("feedEntries", "feedID", feed.ID)) } -func (c *Controller) getSubscriptionFormTemplateArgs(ctx *core.Context, user *model.User) (tplParams, error) { +func (c *Controller) getSubscriptionFormTemplateArgs(ctx *handler.Context, user *model.User) (tplParams, error) { args, err := c.getCommonTemplateArgs(ctx) if err != nil { return nil, err diff --git a/server/ui/controller/unread.go b/ui/unread.go similarity index 87% rename from server/ui/controller/unread.go rename to ui/unread.go index 1dd7b07235f47a6872d18aeebc3dee7c46cc5529..75536ccc64549f11149926340993a520e0eb57a8 100644 --- a/server/ui/controller/unread.go +++ b/ui/unread.go @@ -2,15 +2,15 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" ) // ShowUnreadPage render the page with all unread entries. -func (c *Controller) ShowUnreadPage(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) ShowUnreadPage(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() offset := request.QueryIntegerParam("offset", 0) diff --git a/server/ui/controller/user.go b/ui/user.go similarity index 84% rename from server/ui/controller/user.go rename to ui/user.go index c5d4dba0704018df828a34da752a3b726f999465..caeb4bfdabe911e4f1e94920ccae8938508c6542 100644 --- a/server/ui/controller/user.go +++ b/ui/user.go @@ -2,19 +2,19 @@ // Use of this source code is governed by the Apache 2.0 // license that can be found in the LICENSE file. -package controller +package ui import ( "errors" + "github.com/miniflux/miniflux/http/handler" "github.com/miniflux/miniflux/logger" "github.com/miniflux/miniflux/model" - "github.com/miniflux/miniflux/server/core" - "github.com/miniflux/miniflux/server/ui/form" + "github.com/miniflux/miniflux/ui/form" ) // ShowUsers shows the list of users. -func (c *Controller) ShowUsers(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) ShowUsers(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() if !user.IsAdmin { @@ -41,7 +41,7 @@ func (c *Controller) ShowUsers(ctx *core.Context, request *core.Request, respons } // CreateUser shows the user creation form. -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) { user := ctx.LoggedUser() if !user.IsAdmin { @@ -62,7 +62,7 @@ func (c *Controller) CreateUser(ctx *core.Context, request *core.Request, respon } // SaveUser validate and save the new user into the database. -func (c *Controller) SaveUser(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) SaveUser(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() if !user.IsAdmin { @@ -110,7 +110,7 @@ func (c *Controller) SaveUser(ctx *core.Context, request *core.Request, response } // EditUser shows the form to edit a user. -func (c *Controller) EditUser(ctx *core.Context, request *core.Request, response *core.Response) { +func (c *Controller) EditUser(ctx *handler.Context, request *handler.Request, response *handler.Response) { user := ctx.LoggedUser() if !user.IsAdmin { @@ -140,7 +140,7 @@ func (c *Controller) EditUser(ctx *core.Context, request *core.Request, response } // UpdateUser validate and update a 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) { user := ctx.LoggedUser() if !user.IsAdmin { @@ -196,7 +196,7 @@ func (c *Controller) UpdateUser(ctx *core.Context, request *core.Request, respon } // RemoveUser deletes a user from the database. -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) { user := ctx.LoggedUser() if !user.IsAdmin { response.HTML().Forbidden() @@ -216,7 +216,7 @@ func (c *Controller) RemoveUser(ctx *core.Context, request *core.Request, respon response.Redirect(ctx.Route("users")) } -func (c *Controller) getUserFromURL(ctx *core.Context, request *core.Request, response *core.Response) (*model.User, error) { +func (c *Controller) getUserFromURL(ctx *handler.Context, request *handler.Request, response *handler.Response) (*model.User, error) { userID, err := request.IntegerParam("userID") if err != nil { response.HTML().BadRequest(err)