mirror of
https://github.com/usememos/memos.git
synced 2025-06-05 22:09:59 +02:00
chore: add service version
This commit is contained in:
@ -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"`
|
||||||
}
|
}
|
||||||
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
Mode: mode,
|
|
||||||
Port: port,
|
return &Profile{
|
||||||
DSN: dsn,
|
Mode: mode,
|
||||||
|
Port: port,
|
||||||
|
DSN: dsn,
|
||||||
|
Version: version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -29,7 +29,8 @@ 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)
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -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 className="updated-time-text">
|
|
||||||
Last updated on <span className="pre-text">{lastUpdatedAt}</span> 🎉
|
|
||||||
</p>
|
</p>
|
||||||
|
<Only when={profile !== undefined}>
|
||||||
|
<p className="updated-time-text">
|
||||||
|
version: <span className="pre-text">{profile?.version}</span> 🎉
|
||||||
|
</p>
|
||||||
|
</Only>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
1
web/src/types/api.d.ts
vendored
1
web/src/types/api.d.ts
vendored
@ -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
4
web/src/types/module/system.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
interface Profile {
|
||||||
|
mode: string;
|
||||||
|
version: string;
|
||||||
|
}
|
Reference in New Issue
Block a user