mirror of
https://github.com/usememos/memos.git
synced 2025-01-04 12:35:14 +03:00
feat: system api with profiles
This commit is contained in:
parent
4f88221bce
commit
b3a431570c
38
.github/workflows/build-and-push-release-image.yml
vendored
Normal file
38
.github/workflows/build-and-push-release-image.yml
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
name: build-and-push-docker-image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
# Run on pushing branches like `release/1.0.0`
|
||||
- "release/v*.*.*"
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Extract build args
|
||||
# Extract version from branch name
|
||||
# Example: branch name `release/v1.0.0` sets up env.VERSION=1.0.0
|
||||
run: |
|
||||
echo "VERSION=${GITHUB_REF_NAME#release/v}" >> $GITHUB_ENV
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_NEOSMEMO_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_NEOSMEMO_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
- name: Build and Push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: ./
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_NEOSMEMO_USERNAME }}/memos:${{ env.VERSION }}
|
@ -4,40 +4,28 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"memos/common"
|
||||
"memos/server"
|
||||
"memos/store"
|
||||
)
|
||||
|
||||
type Main struct {
|
||||
profile *Profile
|
||||
profile *common.Profile
|
||||
|
||||
server *server.Server
|
||||
|
||||
db *store.DB
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
m := Main{}
|
||||
profile := GetProfile()
|
||||
m.profile = &profile
|
||||
|
||||
err := m.Run()
|
||||
if err != nil {
|
||||
fmt.Printf("%+v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Main) Run() error {
|
||||
db := store.NewDB(m.profile.dsn, m.profile.mode)
|
||||
|
||||
db := store.NewDB(m.profile)
|
||||
if err := db.Open(); err != nil {
|
||||
return fmt.Errorf("cannot open db: %w", err)
|
||||
}
|
||||
|
||||
m.db = db
|
||||
|
||||
s := server.NewServer(m.profile.port, m.profile.mode)
|
||||
s := server.NewServer(m.profile)
|
||||
|
||||
s.ShortcutService = store.NewShortcutService(db)
|
||||
s.MemoService = store.NewMemoService(db)
|
||||
@ -53,3 +41,16 @@ func (m *Main) Run() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
profile := common.GetProfile()
|
||||
m := Main{
|
||||
profile: &profile,
|
||||
}
|
||||
|
||||
err := m.Run()
|
||||
if err != nil {
|
||||
fmt.Printf("%+v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package cmd
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -9,12 +9,12 @@ import (
|
||||
)
|
||||
|
||||
type Profile struct {
|
||||
// mode can be "release" or "dev"
|
||||
mode string
|
||||
// port is the binding port for server.
|
||||
port int
|
||||
// dsn points to where Memos stores its own data
|
||||
dsn string
|
||||
// Mode can be "release" or "dev"
|
||||
Mode string `json:"mode"`
|
||||
// Port is the binding port for server.
|
||||
Port int `json:"port"`
|
||||
// DSN points to where Memos stores its own data
|
||||
DSN string `json:"-"`
|
||||
}
|
||||
|
||||
func checkDSN(dataDir string) (string, error) {
|
||||
@ -61,8 +61,8 @@ func GetProfile() Profile {
|
||||
dsn := fmt.Sprintf("file:%s/memos_%s.db", dataDir, mode)
|
||||
|
||||
return Profile{
|
||||
mode: mode,
|
||||
port: port,
|
||||
dsn: dsn,
|
||||
Mode: mode,
|
||||
Port: port,
|
||||
DSN: dsn,
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"fmt"
|
||||
"memos/api"
|
||||
"memos/common"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/securecookie"
|
||||
@ -15,15 +16,15 @@ import (
|
||||
type Server struct {
|
||||
e *echo.Echo
|
||||
|
||||
Profile *common.Profile
|
||||
|
||||
UserService api.UserService
|
||||
MemoService api.MemoService
|
||||
ShortcutService api.ShortcutService
|
||||
ResourceService api.ResourceService
|
||||
|
||||
port int
|
||||
}
|
||||
|
||||
func NewServer(port int, mode string) *Server {
|
||||
func NewServer(profile *common.Profile) *Server {
|
||||
e := echo.New()
|
||||
e.Debug = true
|
||||
e.HideBanner = true
|
||||
@ -46,17 +47,19 @@ func NewServer(port int, mode string) *Server {
|
||||
HTML5: true,
|
||||
}))
|
||||
|
||||
// In dev mode, set the const secret key to make login session persistence.
|
||||
secret := []byte("justmemos")
|
||||
if mode != "dev" {
|
||||
if profile.Mode == "release" {
|
||||
secret = securecookie.GenerateRandomKey(16)
|
||||
}
|
||||
e.Use(session.Middleware(sessions.NewCookieStore(secret)))
|
||||
|
||||
s := &Server{
|
||||
e: e,
|
||||
port: port,
|
||||
e: e,
|
||||
Profile: profile,
|
||||
}
|
||||
|
||||
// Webhooks api skips auth checker.
|
||||
webhookGroup := e.Group("/h")
|
||||
s.registerWebhookRoutes(webhookGroup)
|
||||
|
||||
@ -64,6 +67,7 @@ func NewServer(port int, mode string) *Server {
|
||||
apiGroup.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return BasicAuthMiddleware(s.UserService, next)
|
||||
})
|
||||
s.registerSystemRoutes(apiGroup)
|
||||
s.registerAuthRoutes(apiGroup)
|
||||
s.registerUserRoutes(apiGroup)
|
||||
s.registerMemoRoutes(apiGroup)
|
||||
@ -74,5 +78,5 @@ func NewServer(port int, mode string) *Server {
|
||||
}
|
||||
|
||||
func (server *Server) Run() error {
|
||||
return server.e.Start(fmt.Sprintf(":%d", server.port))
|
||||
return server.e.Start(fmt.Sprintf(":%d", server.Profile.Port))
|
||||
}
|
||||
|
19
server/system.go
Normal file
19
server/system.go
Normal file
@ -0,0 +1,19 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
func (s *Server) registerSystemRoutes(g *echo.Group) {
|
||||
g.GET("/ping", func(c echo.Context) error {
|
||||
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)
|
||||
if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(s.Profile)); err != nil {
|
||||
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose system profile").SetInternal(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
@ -36,7 +36,7 @@ CREATE TABLE memo (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
|
||||
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
|
||||
-- allowed row status are 'NORMAL', 'HIDDEN'.
|
||||
-- allowed row status are 'NORMAL', 'PINNED', 'HIDDEN'.
|
||||
row_status TEXT NOT NULL DEFAULT 'NORMAL',
|
||||
content TEXT NOT NULL DEFAULT '',
|
||||
creator_id INTEGER NOT NULL,
|
||||
@ -69,7 +69,7 @@ CREATE TABLE shortcut (
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
payload TEXT NOT NULL DEFAULT '',
|
||||
creator_id INTEGER NOT NULL,
|
||||
-- allowed row status are 'NORMAL', 'ARCHIVED'.
|
||||
-- allowed row status are 'NORMAL', 'PINNED'.
|
||||
row_status TEXT NOT NULL DEFAULT 'NORMAL',
|
||||
FOREIGN KEY(creator_id) REFERENCES users(id)
|
||||
);
|
||||
|
@ -1,4 +1,10 @@
|
||||
INSERT INTO memo
|
||||
(`content`, `creator_id`)
|
||||
INSERT INTO
|
||||
memo (
|
||||
`content`,
|
||||
`creator_id`
|
||||
)
|
||||
VALUES
|
||||
('👋 Welcome to memos', 101);
|
||||
(
|
||||
'#memos 👋 Welcome to memos',
|
||||
101
|
||||
);
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"memos/common"
|
||||
"sort"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
@ -19,18 +20,17 @@ var seedFS embed.FS
|
||||
|
||||
type DB struct {
|
||||
Db *sql.DB
|
||||
|
||||
// datasource name
|
||||
DSN string
|
||||
// mode: release or dev
|
||||
// mode should be release or dev
|
||||
mode string
|
||||
}
|
||||
|
||||
// NewDB returns a new instance of DB associated with the given datasource name.
|
||||
func NewDB(dsn string, mode string) *DB {
|
||||
func NewDB(profile *common.Profile) *DB {
|
||||
db := &DB{
|
||||
DSN: dsn,
|
||||
mode: mode,
|
||||
DSN: profile.DSN,
|
||||
mode: profile.Mode,
|
||||
}
|
||||
return db
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user