chore: add service version

pull/57/head
boojack 3 years ago
parent 5d0e9724db
commit 74ab42069f

@ -0,0 +1 @@
0.0.1

@ -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,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 {

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