Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: migrate bookmark static pages to new http server #775

Merged
merged 27 commits into from Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e08a22c
migrate bookmark content route to new http server
fmartingr Nov 11, 2023
4159d5e
new archive page
fmartingr Nov 12, 2023
776b86b
Merge remote-tracking branch 'origin/master' into feat/bookmark-http-new
fmartingr Nov 12, 2023
46f5645
Merge remote-tracking branch 'origin/master' into feat/bookmark-http-new
fmartingr Nov 12, 2023
1b49d90
remove unused go generate comment
fmartingr Nov 18, 2023
bb84c19
database mock
fmartingr Nov 18, 2023
600e741
utils cleanup
fmartingr Nov 18, 2023
887d23f
unused var
fmartingr Nov 18, 2023
68f12ef
domains refactor and tests
fmartingr Nov 18, 2023
7a2ad09
Merge remote-tracking branch 'origin/master' into feat/bookmark-http-new
fmartingr Nov 18, 2023
939f394
fixed secret key type
fmartingr Dec 10, 2023
336528d
redirect to login on ui errors
fmartingr Dec 10, 2023
bb64c1e
fixed archive folder with storage domain
fmartingr Dec 10, 2023
0e971a7
webroot documentation
fmartingr Dec 10, 2023
f32035b
some bookmark route tests
fmartingr Dec 10, 2023
d64b2b4
fixed error in bookmark domain for non existant bookmarks
fmartingr Dec 10, 2023
0f9eb6c
centralice errors
fmartingr Dec 10, 2023
9953175
Merge remote-tracking branch 'origin/master' into feat/bookmark-http-new
fmartingr Dec 10, 2023
0bcf5d9
add coverage data to unittests
fmartingr Dec 10, 2023
76dccde
Merge remote-tracking branch 'origin/master' into feat/bookmark-http-new
fmartingr Dec 10, 2023
f1a1305
added tests, refactor storage to use afero
fmartingr Dec 17, 2023
692b157
removed mock to avoid increasing complexity
fmartingr Dec 25, 2023
467e296
using deps to copy files around
fmartingr Dec 25, 2023
230fab4
remove config usage (to deps)
fmartingr Dec 25, 2023
dc1ee48
remove handler-ui file
fmartingr Dec 25, 2023
c5fbc1d
Merge branch 'master' into feat/bookmark-http-new
fmartingr Dec 27, 2023
15c19df
Merge remote-tracking branch 'origin/master' into feat/bookmark-http-new
fmartingr Dec 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile
Expand Up @@ -94,3 +94,8 @@ build: clean
coverage:
$(GO) test $(GO_TEST_FLAGS) -coverprofile=coverage.txt ./...
$(GO) tool cover -html=coverage.txt

## Run generate accross the project
.PHONY: generated
generate:
$(GO) generate ./...
42 changes: 30 additions & 12 deletions docs/Configuration.md
@@ -1,35 +1,53 @@
Content
---
# Configuration

<!-- TOC -->

- [Content](#content)
- [Data Directory](#data-directory)
- [Webroot](#webroot)
- [Nginx](#nginx)
- [Database](#database)
- [MySQL](#mysql)
- [PostgreSQL](#postgresql)
- [MySQL](#mysql)
- [PostgreSQL](#postgresql)

<!-- /TOC -->

Data Directory
---
## Data Directory

Shiori is designed to work out of the box, but you can change where it stores your bookmarks if you need to.

By default, Shiori saves your bookmarks in one of the following directories:

| Platform | Directory |
|----------|--------------------------------------------------------------|
| Platform | Directory |
| -------- | ------------------------------------------------------------ |
| Linux | `${XDG_DATA_HOME}/shiori` (default: `~/.local/share/shiori`) |
| macOS | `~/Library/Application Support/shiori` |
| macOS | `~/Library/Application Support/shiori` |
| Windows | `%LOCALAPPDATA%/shiori` |

If you pass the flag `--portable` to Shiori, your data will be stored in the `shiori-data` subdirectory alongside the shiori executable.

To specify a custom path, set the `SHIORI_DIR` environment variable.

Database
---
## Webroot

If you want to serve Shiori behind a reverse proxy, you can set the `SHIORI_WEBROOT` environment variable to the path where Shiori is served, e.g. `/shiori`.

Keep in mind this configuration wont make Shiori accessible from `/shiori` path so you need to setup your reverse proxy accordingly so it can strip the webroot path.

We provide some examples for popular reverse proxies below. Please follow your reverse proxy documentation in order to setup it properly.

### Nginx

Fox nginx, you can use the following configuration as a example. The important part **is the trailing slash in `proxy_pass` directive**:

```nginx
location /shiori {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
```

## Database

Shiori uses an SQLite3 database stored in the above data directory by default. If you prefer, you can also use MySQL or PostgreSQL database by setting it in environment variables.

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -7,7 +7,6 @@ require (
github.com/PuerkitoBio/goquery v1.8.1
github.com/disintegration/imaging v1.6.2
github.com/fatih/color v1.16.0
github.com/gin-contrib/gzip v0.0.6
github.com/gin-contrib/requestid v0.0.6
github.com/gin-contrib/static v0.0.1
github.com/gin-gonic/gin v1.9.1
Expand All @@ -27,6 +26,7 @@ require (
github.com/sethvargo/go-envconfig v0.9.0
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92
github.com/sirupsen/logrus v1.9.3
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.8.4
github.com/swaggo/files v1.0.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Expand Up @@ -212,6 +212,8 @@ github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/add.go
Expand Up @@ -45,7 +45,7 @@
excerpt = normalizeSpace(excerpt)

// Create bookmark item
book := model.Bookmark{
book := model.BookmarkDTO{

Check warning on line 48 in internal/cmd/add.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/add.go#L48

Added line #L48 was not covered by tests
URL: url,
Title: title,
Excerpt: excerpt,
Expand Down Expand Up @@ -101,7 +101,7 @@
KeepExcerpt: excerpt != "",
}

book, isFatalErr, err = core.ProcessBookmark(request)
book, isFatalErr, err = core.ProcessBookmark(deps, request)

Check warning on line 104 in internal/cmd/add.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/add.go#L104

Added line #L104 was not covered by tests
content.Close()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/check.go
Expand Up @@ -76,7 +76,7 @@
for i, book := range bookmarks {
wg.Add(1)

go func(i int, book model.Bookmark) {
go func(i int, book model.BookmarkDTO) {

Check warning on line 79 in internal/cmd/check.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/check.go#L79

Added line #L79 was not covered by tests
// Make sure to finish the WG
defer wg.Done()

Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/import.go
Expand Up @@ -52,7 +52,7 @@
defer srcFile.Close()

// Parse bookmark's file
bookmarks := []model.Bookmark{}
bookmarks := []model.BookmarkDTO{}

Check warning on line 55 in internal/cmd/import.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/import.go#L55

Added line #L55 was not covered by tests
mapURL := make(map[string]struct{})

doc, err := goquery.NewDocumentFromReader(srcFile)
Expand Down Expand Up @@ -135,7 +135,7 @@
}

// Add item to list
bookmark := model.Bookmark{
bookmark := model.BookmarkDTO{

Check warning on line 138 in internal/cmd/import.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/import.go#L138

Added line #L138 was not covered by tests
URL: url,
Title: title,
Tags: tags,
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/pocket.go
Expand Up @@ -36,7 +36,7 @@
defer srcFile.Close()

// Parse pocket's file
bookmarks := []model.Bookmark{}
bookmarks := []model.BookmarkDTO{}

Check warning on line 39 in internal/cmd/pocket.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/pocket.go#L39

Added line #L39 was not covered by tests
mapURL := make(map[string]struct{})

doc, err := goquery.NewDocumentFromReader(srcFile)
Expand Down Expand Up @@ -93,7 +93,7 @@
}

// Add item to list
bookmark := model.Bookmark{
bookmark := model.BookmarkDTO{

Check warning on line 96 in internal/cmd/pocket.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/pocket.go#L96

Added line #L96 was not covered by tests
URL: url,
Title: title,
Modified: modified.Format(model.DatabaseDateFormat),
Expand Down
12 changes: 8 additions & 4 deletions internal/cmd/root.go
Expand Up @@ -8,9 +8,11 @@

"github.com/go-shiori/shiori/internal/config"
"github.com/go-shiori/shiori/internal/database"
"github.com/go-shiori/shiori/internal/dependencies"
"github.com/go-shiori/shiori/internal/domains"
"github.com/go-shiori/shiori/internal/model"
"github.com/sirupsen/logrus"
"github.com/spf13/afero"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)
Expand Down Expand Up @@ -47,7 +49,7 @@
return rootCmd
}

func initShiori(ctx context.Context, cmd *cobra.Command) (*config.Config, *config.Dependencies) {
func initShiori(ctx context.Context, cmd *cobra.Command) (*config.Config, *dependencies.Dependencies) {

Check warning on line 52 in internal/cmd/root.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/root.go#L52

Added line #L52 was not covered by tests
logger := logrus.New()

portableMode, _ := cmd.Flags().GetBool("portable")
Expand Down Expand Up @@ -96,9 +98,11 @@
logger.Warn("Development mode is ENABLED, this will enable some helpers for local development, unsuitable for production environments")
}

dependencies := config.NewDependencies(logger, db, cfg)
dependencies.Domains.Auth = domains.NewAccountsDomain(logger, cfg.Http.SecretKey, db)
dependencies.Domains.Archiver = domains.NewArchiverDomain(logger, cfg.Storage.DataDir)
dependencies := dependencies.NewDependencies(logger, db, cfg)
dependencies.Domains.Auth = domains.NewAccountsDomain(dependencies)
dependencies.Domains.Archiver = domains.NewArchiverDomain(dependencies)
dependencies.Domains.Bookmarks = domains.NewBookmarksDomain(dependencies)
dependencies.Domains.Storage = domains.NewStorageDomain(dependencies, afero.NewBasePathFs(afero.NewOsFs(), cfg.Storage.DataDir))

Check warning on line 105 in internal/cmd/root.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/root.go#L101-L105

Added lines #L101 - L105 were not covered by tests

// Workaround: Get accounts to make sure at least one is present in the database.
// If there's no accounts in the database, create the shiori/gopher account the legacy api
Expand Down
7 changes: 5 additions & 2 deletions internal/cmd/server.go
Expand Up @@ -37,7 +37,7 @@
rootPath, _ := cmd.Flags().GetString("webroot")
accessLog, _ := cmd.Flags().GetBool("access-log")
serveWebUI, _ := cmd.Flags().GetBool("serve-web-ui")
secretKey, _ := cmd.Flags().GetString("secret-key")
secretKey, _ := cmd.Flags().GetBytesHex("secret-key")

Check warning on line 40 in internal/cmd/server.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/server.go#L40

Added line #L40 was not covered by tests

cfg, dependencies := initShiori(ctx, cmd)

Expand Down Expand Up @@ -66,7 +66,10 @@

dependencies.Log.Infof("Starting Shiori v%s", model.BuildVersion)

server := http.NewHttpServer(dependencies.Log).Setup(cfg, dependencies)
server, err := http.NewHttpServer(dependencies.Log).Setup(cfg, dependencies)
if err != nil {
dependencies.Log.WithError(err).Fatal("error setting up server")
}

Check warning on line 72 in internal/cmd/server.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/server.go#L69-L72

Added lines #L69 - L72 were not covered by tests

if err := server.Start(ctx); err != nil {
dependencies.Log.WithError(err).Fatal("error starting server")
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/update.go
Expand Up @@ -147,7 +147,7 @@
book.URL = url
}

go func(i int, book model.Bookmark) {
go func(i int, book model.BookmarkDTO) {

Check warning on line 150 in internal/cmd/update.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/update.go#L150

Added line #L150 was not covered by tests
// Make sure to finish the WG
defer wg.Done()

Expand Down Expand Up @@ -175,7 +175,7 @@
LogArchival: logArchival,
}

book, _, err = core.ProcessBookmark(request)
book, _, err = core.ProcessBookmark(deps, request)

Check warning on line 178 in internal/cmd/update.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/update.go#L178

Added line #L178 was not covered by tests
content.Close()

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/utils.go
Expand Up @@ -41,7 +41,7 @@
return err == nil && tmp.Scheme != "" && tmp.Hostname() != ""
}

func printBookmarks(bookmarks ...model.Bookmark) {
func printBookmarks(bookmarks ...model.BookmarkDTO) {

Check warning on line 44 in internal/cmd/utils.go

View check run for this annotation

Codecov / codecov/patch

internal/cmd/utils.go#L44

Added line #L44 was not covered by tests
for _, bookmark := range bookmarks {
// Create bookmark index
strBookmarkIndex := fmt.Sprintf("%d. ", bookmark.ID)
Expand Down
6 changes: 3 additions & 3 deletions internal/config/config.go
Expand Up @@ -50,7 +50,7 @@ type HttpConfig struct {
RootPath string `env:"HTTP_ROOT_PATH,default=/"`
AccessLog bool `env:"HTTP_ACCESS_LOG,default=True"`
ServeWebUI bool `env:"HTTP_SERVE_WEB_UI,default=True"`
SecretKey string `env:"HTTP_SECRET_KEY"`
SecretKey []byte `env:"HTTP_SECRET_KEY"`
// Fiber Specific
BodyLimit int `env:"HTTP_BODY_LIMIT,default=1024"`
ReadTimeout time.Duration `env:"HTTP_READ_TIMEOUT,default=10s"`
Expand Down Expand Up @@ -82,13 +82,13 @@ type Config struct {
// SetDefaults sets the default values for the configuration
func (c *HttpConfig) SetDefaults(logger *logrus.Logger) {
// Set a random secret key if not set
if c.SecretKey == "" {
if len(c.SecretKey) == 0 {
logger.Warn("SHIORI_HTTP_SECRET_KEY is not set, using random value. This means that all sessions will be invalidated on server restart.")
randomUUID, err := uuid.NewV4()
if err != nil {
logger.WithError(err).Fatal("couldn't generate a random UUID")
}
c.SecretKey = randomUUID.String()
c.SecretKey = []byte(randomUUID.String())
}
}

Expand Down
25 changes: 0 additions & 25 deletions internal/config/dependencies.go

This file was deleted.

15 changes: 7 additions & 8 deletions internal/core/ebook.go
@@ -1,22 +1,21 @@
package core

import (
"fmt"
"os"
fp "path/filepath"
"strconv"
"strings"

epub "github.com/go-shiori/go-epub"
"github.com/go-shiori/shiori/internal/dependencies"
"github.com/go-shiori/shiori/internal/model"
"github.com/pkg/errors"
)

// GenerateEbook receives a `ProcessRequest` and generates an ebook file in the destination path specified.
// The destination path `dstPath` should include file name with ".epub" extension
// The bookmark model will be used to update the UI based on whether this function is successful or not.
func GenerateEbook(req ProcessRequest, dstPath string) (book model.Bookmark, err error) {

func GenerateEbook(deps *dependencies.Dependencies, req ProcessRequest, dstPath string) (book model.BookmarkDTO, err error) {
book = req.Bookmark

// Make sure bookmark ID is defined
Expand All @@ -27,14 +26,14 @@ func GenerateEbook(req ProcessRequest, dstPath string) (book model.Bookmark, err
// Get current state of bookmark cheak archive and thumb
strID := strconv.Itoa(book.ID)

imagePath := fp.Join(req.DataDir, "thumb", fmt.Sprintf("%d", book.ID))
archivePath := fp.Join(req.DataDir, "archive", fmt.Sprintf("%d", book.ID))
bookmarkThumbnailPath := model.GetThumbnailPath(&book)
bookmarkArchivePath := model.GetArchivePath(&book)

if _, err := os.Stat(imagePath); err == nil {
if deps.Domains.Storage.FileExists(bookmarkThumbnailPath) {
book.ImageURL = fp.Join("/", "bookmark", strID, "thumb")
}

if _, err := os.Stat(archivePath); err == nil {
if deps.Domains.Storage.FileExists(bookmarkArchivePath) {
book.HasArchive = true
}

Expand Down Expand Up @@ -77,7 +76,7 @@ func GenerateEbook(req ProcessRequest, dstPath string) (book model.Bookmark, err
defer tmpFile.Close()

// If everything go well we move ebook to dstPath
err = MoveFileToDestination(dstPath, tmpFile)
err = deps.Domains.Storage.WriteFile(dstPath, tmpFile)
if err != nil {
return book, errors.Wrap(err, "failed move ebook to destination")
}
Expand Down