chore: add service version

This commit is contained in:
boojack
2022-05-17 21:21:13 +08:00
parent 5d0e9724db
commit 74ab42069f
13 changed files with 66 additions and 55 deletions

1
VERSION Normal file
View File

@ -0,0 +1 @@
0.0.1

View File

@ -16,7 +16,7 @@ type Memo struct {
type MemoCreate struct { type MemoCreate struct {
// Standard fields // Standard fields
CreatorID int CreatorID int
// Used to import memos with clearly created ts. // Used to import memos with a clearly created ts.
CreatedTs *int64 `json:"createdTs"` CreatedTs *int64 `json:"createdTs"`
// Domain specific fields // Domain specific fields
@ -27,7 +27,6 @@ type MemoPatch struct {
ID int ID int
// Standard fields // Standard fields
CreatedTs *int64 `json:"createdTs"`
RowStatus *string `json:"rowStatus"` RowStatus *string `json:"rowStatus"`
// Domain specific fields // Domain specific fields
@ -43,5 +42,5 @@ type MemoFind struct {
} }
type MemoDelete struct { type MemoDelete struct {
ID *int `json:"id"` ID int `json:"id"`
} }

View File

@ -1,5 +1,8 @@
package api package api
import "memos/common"
type SystemStatus struct { type SystemStatus struct {
Owner *User `json:"owner"` Owner *User `json:"owner"`
Profile *common.Profile `json:"profile"`
} }

View File

@ -11,10 +11,6 @@ import (
type Main struct { type Main struct {
profile *common.Profile profile *common.Profile
server *server.Server
db *store.DB
} }
func (m *Main) Run() error { func (m *Main) Run() error {
@ -23,15 +19,11 @@ func (m *Main) Run() error {
return fmt.Errorf("cannot open db: %w", err) return fmt.Errorf("cannot open db: %w", err)
} }
m.db = db
s := server.NewServer(m.profile) s := server.NewServer(m.profile)
storeInstance := store.New(db) storeInstance := store.New(db)
s.Store = storeInstance s.Store = storeInstance
m.server = s
if err := s.Run(); err != nil { if err := s.Run(); err != nil {
return err return err
} }
@ -42,7 +34,7 @@ func (m *Main) Run() error {
func Execute() { func Execute() {
profile := common.GetProfile() profile := common.GetProfile()
m := Main{ m := Main{
profile: &profile, profile: profile,
} }
err := m.Run() err := m.Run()

View File

@ -11,10 +11,12 @@ import (
type Profile struct { type Profile struct {
// Mode can be "prod" or "dev" // Mode can be "prod" or "dev"
Mode string `json:"mode"` Mode string `json:"mode"`
// Port is the binding port for server. // Port is the binding port for server
Port int `json:"port"` Port int `json:"port"`
// DSN points to where Memos stores its own data // DSN points to where Memos stores its own data
DSN string `json:"dsn"` DSN string `json:"dsn"`
// Version is the current version of server
Version string `json:"version"`
} }
func checkDSN(dataDir string) (string, error) { func checkDSN(dataDir string) (string, error) {
@ -38,8 +40,22 @@ func checkDSN(dataDir string) (string, error) {
return dataDir, nil return dataDir, nil
} }
func getSystemVersion() string {
absPath, err := filepath.Abs("./VERSION")
if err != nil {
return "0.0.0"
}
data, err := os.ReadFile(absPath)
if err != nil {
return "0.0.0"
}
return string(data)
}
// GetDevProfile will return a profile for dev. // GetDevProfile will return a profile for dev.
func GetProfile() Profile { func GetProfile() *Profile {
mode := os.Getenv("mode") mode := os.Getenv("mode")
if mode != "dev" && mode != "prod" { if mode != "dev" && mode != "prod" {
mode = "dev" mode = "dev"
@ -63,9 +79,12 @@ func GetProfile() Profile {
dsn := fmt.Sprintf("%s/memos_%s.db", dataDir, mode) dsn := fmt.Sprintf("%s/memos_%s.db", dataDir, mode)
return Profile{ version := getSystemVersion()
return &Profile{
Mode: mode, Mode: mode,
Port: port, Port: port,
DSN: dsn, DSN: dsn,
Version: version,
} }
} }

View File

@ -116,7 +116,7 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
} }
memoDelete := &api.MemoDelete{ memoDelete := &api.MemoDelete{
ID: &memoID, ID: memoID,
} }
err = s.Store.DeleteMemo(memoDelete) err = s.Store.DeleteMemo(memoDelete)

View File

@ -30,6 +30,7 @@ func (s *Server) registerSystemRoutes(g *echo.Group) {
systemStatus := api.SystemStatus{ systemStatus := api.SystemStatus{
Owner: ownerUser, Owner: ownerUser,
Profile: s.Profile,
} }
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8) c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)

View File

@ -107,9 +107,6 @@ func patchMemo(db *DB, patch *api.MemoPatch) (*api.Memo, error) {
if v := patch.RowStatus; v != nil { if v := patch.RowStatus; v != nil {
set, args = append(set, "row_status = ?"), append(args, *v) set, args = append(set, "row_status = ?"), append(args, *v)
} }
if v := patch.CreatedTs; v != nil {
set, args = append(set, "created_ts = ?"), append(args, *v)
}
args = append(args, patch.ID) args = append(args, patch.ID)

View File

@ -1,13 +1,13 @@
-- user -- user
CREATE TABLE user ( CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
email TEXT NOT NULL UNIQUE, email TEXT NOT NULL UNIQUE,
role TEXT NOT NULL CHECK (role IN ('OWNER', 'USER')) DEFAULT 'USER', role TEXT NOT NULL CHECK (role IN ('OWNER', 'USER')) DEFAULT 'USER',
name TEXT NOT NULL, name TEXT NOT NULL,
password_hash TEXT NOT NULL, password_hash TEXT NOT NULL,
open_id TEXT NOT NULL UNIQUE, open_id TEXT NOT NULL UNIQUE
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now'))
); );
INSERT INTO INSERT INTO
@ -30,12 +30,12 @@ END;
-- memo -- memo
CREATE TABLE memo ( CREATE TABLE memo (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
creator_id INTEGER NOT NULL,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
-- allowed row status are 'NORMAL', 'ARCHIVED', 'HIDDEN'. -- allowed row status are 'NORMAL', 'ARCHIVED', 'HIDDEN'.
row_status TEXT NOT NULL DEFAULT 'NORMAL', row_status TEXT NOT NULL DEFAULT 'NORMAL',
content TEXT NOT NULL DEFAULT '', content TEXT NOT NULL DEFAULT '',
creator_id INTEGER NOT NULL,
FOREIGN KEY(creator_id) REFERENCES users(id) FOREIGN KEY(creator_id) REFERENCES users(id)
); );
@ -59,12 +59,11 @@ END;
-- shortcut -- shortcut
CREATE TABLE shortcut ( CREATE TABLE shortcut (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
creator_id INTEGER NOT NULL,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')), updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
title TEXT NOT NULL DEFAULT '', title TEXT NOT NULL DEFAULT '',
payload 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', 'ARCHIVED'.
row_status TEXT NOT NULL DEFAULT 'NORMAL', row_status TEXT NOT NULL DEFAULT 'NORMAL',
FOREIGN KEY(creator_id) REFERENCES users(id) FOREIGN KEY(creator_id) REFERENCES users(id)
@ -90,13 +89,13 @@ END;
-- resource -- resource
CREATE TABLE resource ( CREATE TABLE resource (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
creator_id INTEGER NOT NULL,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
filename TEXT NOT NULL DEFAULT '', filename TEXT NOT NULL DEFAULT '',
blob BLOB NOT NULL, blob BLOB NOT NULL,
type TEXT NOT NULL DEFAULT '', type TEXT NOT NULL DEFAULT '',
size INTEGER NOT NULL DEFAULT 0, size INTEGER NOT NULL DEFAULT 0,
created_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
updated_ts BIGINT NOT NULL DEFAULT (strftime('%s', 'now')),
creator_id INTEGER NOT NULL,
FOREIGN KEY(creator_id) REFERENCES users(id) FOREIGN KEY(creator_id) REFERENCES users(id)
); );

View File

@ -1,21 +1,24 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import utils from "../helpers/utils"; import api from "../helpers/api";
import Only from "./common/OnlyWhen";
import { showDialog } from "./Dialog"; import { showDialog } from "./Dialog";
import "../less/about-site-dialog.less"; import "../less/about-site-dialog.less";
interface Props extends DialogProps {} interface Props extends DialogProps {}
const AboutSiteDialog: React.FC<Props> = ({ destroy }: Props) => { const AboutSiteDialog: React.FC<Props> = ({ destroy }: Props) => {
const [lastUpdatedAt, setLastUpdatedAt] = useState(""); const [profile, setProfile] = useState<Profile>();
useEffect(() => { useEffect(() => {
try { try {
fetch("https://api.github.com/repos/justmemos/memos/commits/main").then(async (res) => { api.getSystemStatus().then(({ profile }) => {
const data = (await res.json()) as any; setProfile(profile);
setLastUpdatedAt(utils.getDateTimeString(new Date(data.commit.committer.date)));
}); });
} catch (error) { } catch (error) {
setLastUpdatedAt("2017/12/31"); setProfile({
mode: "dev",
version: "0.0.0",
});
} }
}, []); }, []);
@ -35,16 +38,17 @@ const AboutSiteDialog: React.FC<Props> = ({ destroy }: Props) => {
</div> </div>
<div className="dialog-content-container"> <div className="dialog-content-container">
<p> <p>
Memos is an open source, quickly self-hosted alternative <a href="https://flomoapp.com">flomo</a>. Memos is an open source, quickly self-hosted alternative to <a href="https://flomoapp.com">flomo</a>.
</p> </p>
<br /> <br />
<p> <p>
🏗 <a href="https://github.com/justmemos/memos">This project</a> is working in progress, and very pleasure to your{" "} <a href="https://github.com/justmemos/memos">🏗 Source code</a>, and built by <a href="https://github.com/boojack">Steven 🐯</a>.
<a href="https://github.com/justmemos/memos/issues">PRs</a>.
</p> </p>
<Only when={profile !== undefined}>
<p className="updated-time-text"> <p className="updated-time-text">
Last updated on <span className="pre-text">{lastUpdatedAt}</span> 🎉 version: <span className="pre-text">{profile?.version}</span> 🎉
</p> </p>
</Only>
</div> </div>
</> </>
); );

View File

@ -2,7 +2,7 @@
.about-site-dialog { .about-site-dialog {
> .dialog-container { > .dialog-container {
@apply w-128; @apply w-96;
> .dialog-content-container { > .dialog-content-container {
@apply leading-relaxed; @apply leading-relaxed;
@ -20,15 +20,6 @@
@apply font-mono; @apply font-mono;
} }
> .btn {
@apply px-2 py-1 text-white rounded text-sm;
background-color: @text-green;
&:hover {
@apply opacity-80;
}
}
a { a {
@apply cursor-pointer underline-offset-2 underline text-blue-600; @apply cursor-pointer underline-offset-2 underline text-blue-600;
} }

View File

@ -1,6 +1,7 @@
declare namespace API { declare namespace API {
interface SystemStatus { interface SystemStatus {
owner: Model.User; owner: Model.User;
profile: Profile;
} }
interface UserCreate { interface UserCreate {

4
web/src/types/module/system.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
interface Profile {
mode: string;
version: string;
}