Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
5b4f4a3fea | |||
af92d19570 |
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
/result*
|
||||
/repl-result*
|
||||
temp/
|
||||
.tmp
|
||||
|
||||
dist/
|
||||
/.venv
|
||||
|
@ -1 +0,0 @@
|
||||
::: materia.app
|
@ -1 +0,0 @@
|
||||
::: materia.core
|
@ -1 +0,0 @@
|
||||
::: materia.models
|
@ -1 +0,0 @@
|
||||
::: materia.routers
|
@ -1 +0,0 @@
|
||||
::: materia.security
|
@ -1 +0,0 @@
|
||||
::: materia.tasks
|
16
flake.lock
@ -207,6 +207,21 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-std": {
|
||||
"locked": {
|
||||
"lastModified": 1710870712,
|
||||
"narHash": "sha256-e+7MJF2gsgTBuOWv4mCimSP0D9+naeFSw9a7N3yEmv4=",
|
||||
"owner": "chessai",
|
||||
"repo": "nix-std",
|
||||
"rev": "31bbc925750cc9d8f828fe55cee1a2bd985e0c00",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "chessai",
|
||||
"repo": "nix-std",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-mailserver": {
|
||||
"inputs": {
|
||||
"blobs": "blobs",
|
||||
@ -437,6 +452,7 @@
|
||||
"inputs": {
|
||||
"bonfire": "bonfire",
|
||||
"dream2nix": "dream2nix",
|
||||
"nix-std": "nix-std",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
}
|
||||
},
|
||||
|
535
flake.nix
@ -8,6 +8,7 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
bonfire.url = "github:L-Nafaryus/bonfire";
|
||||
nix-std.url = "github:chessai/nix-std";
|
||||
};
|
||||
|
||||
outputs = {
|
||||
@ -15,6 +16,7 @@
|
||||
nixpkgs,
|
||||
dream2nix,
|
||||
bonfire,
|
||||
nix-std,
|
||||
...
|
||||
}: let
|
||||
system = "x86_64-linux";
|
||||
@ -43,45 +45,6 @@
|
||||
// {inherit meta;};
|
||||
in {
|
||||
packages.x86_64-linux = {
|
||||
materia-server = dreamBuildPackage {
|
||||
module = {
|
||||
config,
|
||||
lib,
|
||||
dream2nix,
|
||||
...
|
||||
}: {
|
||||
imports = [dream2nix.modules.dream2nix.WIP-python-pdm];
|
||||
|
||||
pdm.lockfile = ./pdm.lock;
|
||||
pdm.pyproject = ./pyproject.toml;
|
||||
|
||||
deps = _: {
|
||||
python = pkgs.python312;
|
||||
};
|
||||
|
||||
mkDerivation = {
|
||||
src = ./.;
|
||||
buildInputs = [
|
||||
pkgs.python312.pkgs.pdm-backend
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
pkgs.python312.pkgs.wrapPython
|
||||
];
|
||||
configurePhase = ''
|
||||
${lib.getExe pkgs.mkdocs} build -d src/materia/docs/
|
||||
'';
|
||||
# TODO: include docs
|
||||
};
|
||||
};
|
||||
meta = with nixpkgs.lib; {
|
||||
description = "Materia";
|
||||
license = licenses.mit;
|
||||
maintainers = with bonLib.maintainers; [L-Nafaryus];
|
||||
broken = false;
|
||||
mainProgram = "materia";
|
||||
};
|
||||
};
|
||||
|
||||
materia-frontend-vue = dreamBuildPackage {
|
||||
module = {
|
||||
lib,
|
||||
@ -97,11 +60,7 @@
|
||||
];
|
||||
|
||||
mkDerivation = {
|
||||
src = ./workspaces/frontend;
|
||||
configurePhase = ''
|
||||
${self.packages.x86_64-linux.materia-server}/bin/materia export openapi --path ./
|
||||
npm run openapi
|
||||
'';
|
||||
src = ./packages/frontend;
|
||||
};
|
||||
|
||||
deps = {nixpkgs, ...}: {
|
||||
@ -117,7 +76,8 @@
|
||||
};
|
||||
};
|
||||
meta = with nixpkgs.lib; {
|
||||
description = "Materia frontend (nodejs)";
|
||||
description = "Materia is a simple and fast cloud storage (vue)";
|
||||
homepage = "https://materia.elnafo.ru";
|
||||
license = licenses.mit;
|
||||
maintainers = with bonLib.maintainers; [L-Nafaryus];
|
||||
broken = false;
|
||||
@ -137,71 +97,129 @@
|
||||
}: {
|
||||
imports = [dream2nix.modules.dream2nix.WIP-python-pdm];
|
||||
|
||||
pdm.lockfile = ./workspaces/frontend/pdm.lock;
|
||||
pdm.pyproject = ./workspaces/frontend/pyproject.toml;
|
||||
pdm.lockfile = ./pdm.lock;
|
||||
pdm.pyproject = ./packages/frontend/pyproject.toml;
|
||||
|
||||
deps = _: {
|
||||
python = pkgs.python312;
|
||||
};
|
||||
|
||||
mkDerivation = {
|
||||
src = ./workspaces/frontend;
|
||||
src = ./packages/frontend;
|
||||
buildInputs = [
|
||||
pkgs.python312.pkgs.pdm-backend
|
||||
];
|
||||
configurePhase = ''
|
||||
cp -rv ${materia-frontend-vue}/dist ./src/materia_frontend/
|
||||
mkdir -p target/materia_frontend
|
||||
cp -rv ${materia-frontend-vue}/dist/* ./target/materia_frontend/
|
||||
cp -rv templates ./target/materia_frontend/
|
||||
touch target/materia_frontend/__init__.py
|
||||
'';
|
||||
};
|
||||
};
|
||||
meta = with nixpkgs.lib; {
|
||||
description = "Materia frontend";
|
||||
description = "Materia is a simple and fast cloud storage (frontend)";
|
||||
homepage = "https://materia.elnafo.ru";
|
||||
license = licenses.mit;
|
||||
maintainers = with bonLib.maintainers; [L-Nafaryus];
|
||||
broken = false;
|
||||
};
|
||||
};
|
||||
|
||||
materia = dreamBuildPackage {
|
||||
materia-server = pkgs.callPackage ({
|
||||
withFrontend ? true,
|
||||
withDocs ? true,
|
||||
...
|
||||
}:
|
||||
dreamBuildPackage {
|
||||
extraArgs = {
|
||||
inherit (self.packages.x86_64-linux) materia-frontend;
|
||||
inherit (self.packages.x86_64-linux) materia-frontend materia-docs;
|
||||
};
|
||||
module = {
|
||||
config,
|
||||
lib,
|
||||
dream2nix,
|
||||
materia-frontend,
|
||||
materia-docs,
|
||||
...
|
||||
}: {
|
||||
imports = [dream2nix.modules.dream2nix.WIP-python-pdm];
|
||||
|
||||
pdm.lockfile = ./pdm.lock;
|
||||
pdm.pyproject = ./pyproject.toml;
|
||||
pdm.pyproject = ./packages/server/pyproject.toml;
|
||||
|
||||
deps = _: {
|
||||
python = pkgs.python312;
|
||||
};
|
||||
|
||||
mkDerivation = {
|
||||
src = ./.;
|
||||
src = ./packages/server;
|
||||
buildInputs = [
|
||||
pkgs.python312.pkgs.pdm-backend
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
pkgs.python312.pkgs.wrapPython
|
||||
];
|
||||
propagatedBuildInputs = [
|
||||
propagatedBuildInputs =
|
||||
lib.optionals withFrontend [
|
||||
materia-frontend
|
||||
];
|
||||
]
|
||||
++ lib.optionals withDocs [materia-docs];
|
||||
};
|
||||
};
|
||||
meta = with nixpkgs.lib; {
|
||||
description = "Materia";
|
||||
description = "Materia is a simple and fast cloud storage";
|
||||
homepage = "https://materia.elnafo.ru";
|
||||
license = licenses.mit;
|
||||
maintainers = with bonLib.maintainers; [L-Nafaryus];
|
||||
broken = false;
|
||||
mainProgram = "materia";
|
||||
};
|
||||
}) {};
|
||||
|
||||
materia-docs = dreamBuildPackage {
|
||||
extraArgs = {
|
||||
materia-server = self.packages.x86_64-linux.materia-server.override {
|
||||
withFrontend = false;
|
||||
withDocs = false;
|
||||
};
|
||||
};
|
||||
module = {
|
||||
config,
|
||||
lib,
|
||||
dream2nix,
|
||||
materia-server,
|
||||
...
|
||||
}: {
|
||||
imports = [dream2nix.modules.dream2nix.WIP-python-pdm];
|
||||
|
||||
pdm.lockfile = ./pdm.lock;
|
||||
pdm.pyproject = ./packages/docs/pyproject.toml;
|
||||
|
||||
deps = _: {
|
||||
python = pkgs.python312;
|
||||
};
|
||||
|
||||
mkDerivation = {
|
||||
src = ./packages/docs;
|
||||
buildInputs = [
|
||||
pkgs.python312.pkgs.pdm-backend
|
||||
];
|
||||
nativeBuildInputs = [pkgs.mkdocs materia-server];
|
||||
configurePhase = ''
|
||||
mkdir -p target/materia_docs
|
||||
mkdocs build
|
||||
touch target/materia_docs/__init__.py
|
||||
'';
|
||||
};
|
||||
};
|
||||
meta = with nixpkgs.lib; {
|
||||
description = "Materia is a simple and fast cloud storage (docs)";
|
||||
homepage = "https://materia.elnafo.ru";
|
||||
license = licenses.mit;
|
||||
maintainers = with bonLib.maintainers; [L-Nafaryus];
|
||||
broken = false;
|
||||
};
|
||||
};
|
||||
|
||||
postgresql-devel = bonfire.packages.x86_64-linux.postgresql;
|
||||
@ -224,7 +242,7 @@
|
||||
pathsToLink = ["/bin" "/etc" "/"];
|
||||
paths = with pkgs; [
|
||||
bash
|
||||
self.packages.x86_64-linux.materia
|
||||
self.packages.x86_64-linux.materia-server
|
||||
entryPoint
|
||||
];
|
||||
};
|
||||
@ -257,5 +275,406 @@
|
||||
# greenlet requires libstdc++
|
||||
LD_LIBRARY_PATH = nixpkgs.lib.makeLibraryPath [pkgs.stdenv.cc.cc];
|
||||
};
|
||||
|
||||
nixosModules = rec {
|
||||
materia = {
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.services.materia;
|
||||
in {
|
||||
options.services.materia = {
|
||||
enable = mkEnableOption "Enables the Materia service";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = self.packages.x86_64-linux.materia-server;
|
||||
description = "The package to use.";
|
||||
};
|
||||
|
||||
application = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
mode = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
working_directory = mkOption {
|
||||
type = types.path;
|
||||
default = "/var/lib/materia";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
user = "materia";
|
||||
group = "materia";
|
||||
mode = "production";
|
||||
working_directory = "/var/lib/materia";
|
||||
};
|
||||
};
|
||||
|
||||
server = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
scheme = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
};
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
scheme = "http";
|
||||
address = "127.0.0.1";
|
||||
port = 54601;
|
||||
domain = "localhost";
|
||||
};
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
backend = mkOption {
|
||||
type = types.str;
|
||||
default = "postgresql";
|
||||
};
|
||||
scheme = mkOption {
|
||||
type = types.str;
|
||||
default = "postgresql+asyncpg";
|
||||
};
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5432;
|
||||
};
|
||||
name = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = "materia";
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "materia";
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.nullOr (types.oneOf [types.str types.path]);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
backend = "postgresql";
|
||||
scheme = "postgresql+asyncpg";
|
||||
address = "127.0.0.1";
|
||||
port = 5432;
|
||||
name = "materia";
|
||||
user = "materia";
|
||||
password = null;
|
||||
};
|
||||
};
|
||||
|
||||
cache = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
backend = mkOption {
|
||||
type = types.str;
|
||||
default = "redis";
|
||||
};
|
||||
scheme = mkOption {
|
||||
type = types.str;
|
||||
default = "redis";
|
||||
};
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 6379;
|
||||
};
|
||||
database = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = 0;
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "materia";
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.nullOr (types.oneOf [types.str types.path]);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
backed = "redis";
|
||||
scheme = "redis";
|
||||
address = "127.0.0.1";
|
||||
port = 6379;
|
||||
database = 0;
|
||||
user = "materia";
|
||||
password = null;
|
||||
};
|
||||
};
|
||||
|
||||
security = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
secret_key = mkOption {
|
||||
type = types.nullOr (types.oneOf [types.str types.path]);
|
||||
};
|
||||
password_min_length = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
password_hash_algo = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
};
|
||||
cookie_http_only = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
cookie_access_token_name = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
cookie_refresh_token_name = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
secret_key = null;
|
||||
password_min_length = 8;
|
||||
password_hash_algo = "bcrypt";
|
||||
cookie_http_only = true;
|
||||
cookie_access_token_name = "materia_at";
|
||||
cookie_refresh_token_name = "materia_rt";
|
||||
};
|
||||
};
|
||||
|
||||
oauth2 = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enabled = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
jwt_signing_algo = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
jwt_singing_key = mkOption {
|
||||
type = types.nullOr (types.oneOf [types.str types.path]);
|
||||
};
|
||||
jwt_secret = mkOption {
|
||||
type = types.nullOr (types.oneOf [types.str types.path]);
|
||||
};
|
||||
access_token_lifetime = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
refresh_token_lifetime = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
enabled = true;
|
||||
jwt_signing_algo = "HS256";
|
||||
jwt_singing_key = null;
|
||||
jwt_secret = "changeme";
|
||||
access_token_lifetime = 3600;
|
||||
refresh_token_lifetime = 730 * 60;
|
||||
};
|
||||
};
|
||||
|
||||
mailer = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enabled = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
scheme = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
address = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.nullOr types.int;
|
||||
default = null;
|
||||
};
|
||||
helo = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
cert_file = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
};
|
||||
key_file = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
};
|
||||
sender = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
password = mkOption {
|
||||
type = types.nullOr (types.oneOf [types.str types.path]);
|
||||
default = null;
|
||||
};
|
||||
plain_text = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {};
|
||||
};
|
||||
|
||||
cron = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
workers_count = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
workers_count = 1;
|
||||
};
|
||||
};
|
||||
|
||||
repository = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
capacity = mkOption {
|
||||
type = types.int;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {capacity = 5368709120;};
|
||||
};
|
||||
|
||||
misc = mkOption {
|
||||
type = types.submodule {
|
||||
options = {
|
||||
enable_client = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
enable_docs = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
enable_api_docs = mkOption {
|
||||
type = types.bool;
|
||||
};
|
||||
};
|
||||
};
|
||||
default = {
|
||||
enable_client = true;
|
||||
enable_docs = true;
|
||||
enable_api_docs = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users.materia = {
|
||||
description = "Materia service user";
|
||||
home = cfg.application.working_directory;
|
||||
createHome = true;
|
||||
isSystemUser = true;
|
||||
group = "materia";
|
||||
};
|
||||
users.groups.materia = {};
|
||||
|
||||
systemd.services.materia = {
|
||||
description = "Materia service";
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target"];
|
||||
|
||||
serviceConfig = {
|
||||
Restart = "always";
|
||||
ExecStart = "${lib.getExe cfg.package} start";
|
||||
User = "materia";
|
||||
WorkingDirectory = cfg.application.working_directory;
|
||||
};
|
||||
|
||||
preStart = let
|
||||
toTOML = nix-std.lib.serde.toTOML;
|
||||
configFile = pkgs.writeText "config.toml" ''
|
||||
${toTOML {inherit (cfg) application server database cache security oauth2 mailer cron repository misc;}}
|
||||
'';
|
||||
in ''
|
||||
ln -sf ${configFile} ${cfg.application.working_directory}/config.toml
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nixosConfigurations.materia = nixpkgs.lib.nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
self.nixosModules.materia
|
||||
({
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
boot.isContainer = true;
|
||||
|
||||
networking.hostName = "materia";
|
||||
networking.useDHCP = false;
|
||||
|
||||
services.redis.servers.materia = {
|
||||
enable = true;
|
||||
port = 6379;
|
||||
databases = 1;
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
enableTCPIP = true;
|
||||
authentication = ''
|
||||
host materia all 127.0.0.1/32 trust
|
||||
'';
|
||||
initialScript = pkgs.writeText "init" ''
|
||||
CREATE ROLE materia WITH LOGIN PASSWORD 'test';
|
||||
CREATE DATABASE materia OWNER materia;
|
||||
'';
|
||||
ensureDatabases = ["materia"];
|
||||
};
|
||||
|
||||
services.materia = {
|
||||
enable = true;
|
||||
cache.port = config.services.redis.servers.materia.port;
|
||||
database.password = "test";
|
||||
};
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
1
packages/docs/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
@ -1,3 +1,6 @@
|
||||
docs_dir: src
|
||||
site_dir: target/materia_docs
|
||||
|
||||
site_name: Materia Documentation
|
||||
site_description: Materia cloud storage
|
||||
#site_url:
|
||||
@ -53,7 +56,7 @@ plugins:
|
||||
- mkdocstrings:
|
||||
handlers:
|
||||
python:
|
||||
paths: [src] # search packages in the src folder
|
||||
paths: [../server/src] # search packages in the src folder
|
||||
options:
|
||||
extensions:
|
||||
- griffe_typingdoc
|
||||
@ -76,18 +79,6 @@ plugins:
|
||||
filters:
|
||||
- '!^_'
|
||||
|
||||
nav:
|
||||
- Materia: index.md
|
||||
- Reference:
|
||||
- reference/index.md
|
||||
- reference/app.md
|
||||
- reference/core.md
|
||||
- reference/models.md
|
||||
- reference/routers.md
|
||||
- reference/security.md
|
||||
- reference/tasks.md
|
||||
- API: api.md
|
||||
|
||||
markdown_extensions:
|
||||
# Python Markdown
|
||||
abbr:
|
||||
@ -131,3 +122,20 @@ markdown_extensions:
|
||||
pymdownx.blocks.details:
|
||||
pymdownx.blocks.tab:
|
||||
alternate_style: True
|
||||
|
||||
nav:
|
||||
- Usage:
|
||||
- Introduction: index.md
|
||||
- usage/getting-started.md
|
||||
- Reference:
|
||||
- reference/index.md
|
||||
- reference/app.md
|
||||
- reference/core.md
|
||||
- reference/models.md
|
||||
- reference/routers.md
|
||||
- reference/security.md
|
||||
- reference/tasks.md
|
||||
- Development:
|
||||
- devel/contrib.md
|
||||
- devel/local.md
|
||||
- API: api.md
|
40
packages/docs/pyproject.toml
Normal file
@ -0,0 +1,40 @@
|
||||
[project]
|
||||
name = "materia-docs"
|
||||
version = "0.1.1"
|
||||
description = "Materia documentation"
|
||||
authors = [
|
||||
{name = "L-Nafaryus", email = "l.nafaryus@gmail.com"},
|
||||
]
|
||||
dependencies = [
|
||||
"mkdocs-material>=9.5.38",
|
||||
"mkdocstrings-python>=1.11.1",
|
||||
"griffe-typingdoc>=0.2.7",
|
||||
"pymdown-extensions>=10.11",
|
||||
"black<24.0.0,>=23.3.0",
|
||||
]
|
||||
requires-python = ">=3.12,<3.13"
|
||||
license = {text = "MIT"}
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://materia.elnafo.ru"
|
||||
Repository = "https://github.com/L-Nafaryus/materia"
|
||||
Documentation = "https://materia.elnafo.ru/docs"
|
||||
|
||||
[build-system]
|
||||
requires = ["pdm-backend"]
|
||||
build-backend = "pdm.backend"
|
||||
|
||||
[tool.pdm]
|
||||
distribution = true
|
||||
|
||||
[tool.pdm.build]
|
||||
package-dir = "target"
|
||||
includes = ["target/materia_docs"]
|
||||
|
||||
[tool.pdm.scripts]
|
||||
# mkdocs creates "target/materia_docs"
|
||||
mkdocs-build.cmd = "mkdocs build"
|
||||
top-level.shell = "touch target/materia_docs/__init__.py"
|
||||
pre_build.composite = [ "mkdocs-build", "top-level" ]
|
||||
|
||||
doc.cmd = "mkdocs serve"
|
58
packages/docs/src/devel/contrib.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Contributing
|
||||
|
||||
First off, thanks for taking the time to contribute! Contributions include but are not restricted to:
|
||||
|
||||
- Reporting bugs
|
||||
- Contributing to code
|
||||
- Writing tests
|
||||
- Writing documentation
|
||||
|
||||
The following is a set of guidelines for contributing.
|
||||
|
||||
## A recommended flow of contributing to an Open Source project
|
||||
|
||||
This section is for beginners to OSS. If you are an experienced OSS developer, you can skip
|
||||
this section.
|
||||
|
||||
1. First, fork this project to your own namespace using the fork button at the top right of the repository page.
|
||||
2. Clone the **upstream** repository to local:
|
||||
```sh
|
||||
git clone https://github.com/L-Nafaryus/materia.git
|
||||
# Or if you prefer SSH clone:
|
||||
git clone git@github.com:L-Nafaryus/materia.git
|
||||
```
|
||||
3. Add the fork as a new remote:
|
||||
```sh
|
||||
git remote add fork https://github.com/yourname/materia.git
|
||||
git fetch fork
|
||||
```
|
||||
where `fork` is the remote name of the fork repository.
|
||||
|
||||
/// tip
|
||||
|
||||
1. Don't modify code on the master branch, the master branch should always keep track of origin/master.
|
||||
|
||||
To update master branch to date:
|
||||
|
||||
```sh
|
||||
git pull origin master
|
||||
# In rare cases that your local master branch diverges from the remote master:
|
||||
git fetch origin && git reset --hard master
|
||||
```
|
||||
|
||||
2. Create a new branch based on the up-to-date master branch for new patches.
|
||||
3. Create a Pull Request from that patch branch.
|
||||
|
||||
///
|
||||
|
||||
## Local development
|
||||
|
||||
See [Local development](./local.md)
|
||||
|
||||
## Code style
|
||||
|
||||
*Soon*
|
||||
|
||||
## Realease
|
||||
|
||||
*Soon*
|
3
packages/docs/src/devel/local.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Local development
|
||||
|
||||
*Soon*
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
@ -15,7 +15,7 @@
|
||||
<strong><em>Materia is a simple and fast cloud storage</em></strong>
|
||||
</p>
|
||||
|
||||
**Documentation**: [https://storage.elnafo.ru/docs](https://storage.elnafo.ru/docs)
|
||||
**Documentation**: [https://materia.elnafo.ru/docs](https://materia.elnafo.ru/docs)
|
||||
|
||||
**Source**: [https://vcs.elnafo.ru/L-Nafaryus/materia](https://vcs.elnafo.ru/L-Nafaryus/materia)
|
||||
|
||||
@ -148,4 +148,4 @@ pdm build
|
||||
|
||||
## License
|
||||
|
||||
**materia** is licensed under the terms of the [MIT License](LICENSE).
|
||||
**materia** is licensed under the terms of the [MIT License](https://vcs.elnafo.ru/L-Nafaryus/materia/src/branch/master/LICENSE).
|
1
packages/docs/src/reference/app.md
Normal file
@ -0,0 +1 @@
|
||||
::: materia_server.app
|
1
packages/docs/src/reference/core.md
Normal file
@ -0,0 +1 @@
|
||||
::: materia_server.core
|
1
packages/docs/src/reference/models.md
Normal file
@ -0,0 +1 @@
|
||||
::: materia_server.models
|
1
packages/docs/src/reference/routers.md
Normal file
@ -0,0 +1 @@
|
||||
::: materia_server.routers
|
1
packages/docs/src/reference/security.md
Normal file
@ -0,0 +1 @@
|
||||
::: materia_server.security
|
1
packages/docs/src/reference/tasks.md
Normal file
@ -0,0 +1 @@
|
||||
::: materia_server.tasks
|
1
packages/docs/src/usage/getting-started.md
Normal file
@ -0,0 +1 @@
|
||||
# Getting started
|
@ -11,5 +11,6 @@ node_modules/
|
||||
*.mjs
|
||||
*.log
|
||||
|
||||
openapi.json
|
||||
#openapi.json
|
||||
/target
|
||||
src/client
|
@ -2,7 +2,7 @@
|
||||
<html lang="en" class="h-full">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/resources/assets/logo.svg">
|
||||
<link rel="icon" href="/assets/logo.svg">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Materia Dev</title>
|
||||
</head>
|
1
packages/frontend/openapi.json
Normal file
@ -1,15 +1,25 @@
|
||||
{
|
||||
"name": "materia-frontend-vue",
|
||||
"version": "0.1.1",
|
||||
"description": "Materia is a simple and fast cloud storage (vue)",
|
||||
"author": "L-Nafaryus <l.nafaryus@gmail.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://materia.elnafo.ru",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/L-Nafaryus/materia",
|
||||
"directory": "packages/frontend"
|
||||
},
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build-check": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build": "vite build",
|
||||
"simple-build": "vite build",
|
||||
"build": "npm run openapi && vite build",
|
||||
"type-check": "vue-tsc --build --force",
|
||||
"openapi": "openapi-ts --input ./openapi.json --output ./src/client/ --client @hey-api/client-axios"
|
||||
"openapi": "./node_modules/@hey-api/openapi-ts/bin/index.cjs --input ./openapi.json --output ./src/client/ --client @hey-api/client-axios"
|
||||
},
|
||||
"dependencies": {
|
||||
"@catppuccin/tailwindcss": "^0.1.6",
|
35
packages/frontend/pyproject.toml
Normal file
@ -0,0 +1,35 @@
|
||||
[project]
|
||||
name = "materia-frontend"
|
||||
version = "0.1.2"
|
||||
description = "Materia is a simple and fast cloud storage (frontend)"
|
||||
authors = [
|
||||
{name = "L-Nafaryus", email = "l.nafaryus@gmail.com"},
|
||||
]
|
||||
requires-python = ">=3.12,<3.13"
|
||||
license = {text = "MIT"}
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://materia.elnafo.ru"
|
||||
Repository = "https://github.com/L-Nafaryus/materia"
|
||||
Documentation = "https://materia.elnafo.ru/docs"
|
||||
|
||||
[build-system]
|
||||
requires = ["pdm-backend"]
|
||||
build-backend = "pdm.backend"
|
||||
|
||||
[tool.pdm]
|
||||
distribution = true
|
||||
|
||||
[tool.pdm.build]
|
||||
package-dir = "target"
|
||||
includes = ["target/materia_frontend"]
|
||||
|
||||
[tool.pdm.scripts]
|
||||
npm-install.cmd = "npm install"
|
||||
openapi-client.cmd = "npm run openapi"
|
||||
npm-build.cmd = "npm run simple-build -- --outDir target/materia_frontend"
|
||||
top-level.shell = "touch target/materia_frontend/__init__.py"
|
||||
copy-templates.shell = "cp -r ./templates target/materia_frontend/"
|
||||
pre_build.composite = [ "npm-install", "openapi-client", "npm-build", "top-level", "copy-templates" ]
|
||||
|
||||
openapi-json.cmd = "pdm run -p ../server python -m materia_server export openapi --path ./openapi.json"
|
Before Width: | Height: | Size: 842 B After Width: | Height: | Size: 842 B |
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 862 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 702 B After Width: | Height: | Size: 702 B |
@ -9,7 +9,7 @@ export const is_authorized = async (): Promise<boolean> => {
|
||||
.then(async res => { userStore.info = res.data; })
|
||||
.then(async () => {
|
||||
if (!userStore.avatar && userStore.info.avatar) {
|
||||
await api.resourcesAvatar(userStore.info.avatar)
|
||||
await api.avatarAvatar(userStore.info.avatar)
|
||||
.then(async res => { userStore.avatar = res.data; })
|
||||
}
|
||||
})
|
@ -31,7 +31,7 @@ export const useUser = defineStore("user", () => {
|
||||
})
|
||||
.then(async () => {
|
||||
if (!avatar.value && info.value.avatar) {
|
||||
await api.resourcesAvatar(info.value.avatar)
|
||||
await api.avatarAvatar(info.value.avatar)
|
||||
.then(async res => { avatar.value = res.data; })
|
||||
}
|
||||
})
|
@ -2,11 +2,11 @@
|
||||
<html lang="en" class="h-full">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="icon" href="/resources/assets/logo.svg">
|
||||
<link rel="icon" href="/assets/logo.svg">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Materia</title>
|
||||
<script type="module" crossorigin src="/resources/assets/index.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/resources/assets/index.css">
|
||||
<script type="module" crossorigin src="/assets/index.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index.css">
|
||||
</head>
|
||||
<body class="h-full bg-zinc-900 text-zinc-200 font-sans">
|
||||
<div id="{{ view }}" class="flex flex-col h-full"></div>
|
@ -10,12 +10,11 @@ export default defineConfig({
|
||||
vueJsx(),
|
||||
],
|
||||
build: {
|
||||
//outDir: path.resolve(__dirname, "./frontend"),
|
||||
rollupOptions: {
|
||||
output: {
|
||||
entryFileNames: "resources/assets/[name].js",
|
||||
assetFileNames: "resources/assets/[name][extname]",
|
||||
chunkFileNames: "resources/assets/[name].js"
|
||||
entryFileNames: "assets/[name].js",
|
||||
assetFileNames: "assets/[name][extname]",
|
||||
chunkFileNames: "assets/[name].js"
|
||||
}
|
||||
}
|
||||
},
|
18
packages/server/.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/result*
|
||||
/repl-result*
|
||||
temp/
|
||||
|
||||
dist/
|
||||
/.venv
|
||||
__pycache__/
|
||||
*.egg-info
|
||||
|
||||
.pdm.toml
|
||||
.pdm-python
|
||||
.pdm-build
|
||||
|
||||
.pytest_cache
|
||||
.coverage
|
||||
|
||||
/site
|
||||
src/materia/docs
|
114
packages/server/pyproject.toml
Normal file
@ -0,0 +1,114 @@
|
||||
[project]
|
||||
name = "materia-server"
|
||||
version = "0.1.1"
|
||||
description = "Materia is a simple and fast cloud storage"
|
||||
authors = [
|
||||
{name = "L-Nafaryus", email = "l.nafaryus@gmail.com"},
|
||||
]
|
||||
dependencies = [
|
||||
"fastapi<1.0.0,>=0.111.0",
|
||||
"uvicorn[standard]<1.0.0,>=0.29.0",
|
||||
"psycopg2-binary<3.0.0,>=2.9.9",
|
||||
"toml<1.0.0,>=0.10.2",
|
||||
"sqlalchemy[asyncio]<3.0.0,>=2.0.30",
|
||||
"asyncpg<1.0.0,>=0.29.0",
|
||||
"eventlet<1.0.0,>=0.36.1",
|
||||
"bcrypt==4.1.2",
|
||||
"pyjwt<3.0.0,>=2.8.0",
|
||||
"requests<3.0.0,>=2.31.0",
|
||||
"pillow<11.0.0,>=10.3.0",
|
||||
"sqids<1.0.0,>=0.4.1",
|
||||
"alembic<2.0.0,>=1.13.1",
|
||||
"authlib<2.0.0,>=1.3.0",
|
||||
"redis[hiredis]<6.0.0,>=5.0.4",
|
||||
"aiosmtplib<4.0.0,>=3.0.1",
|
||||
"emails<1.0,>=0.6",
|
||||
"pydantic-settings<3.0.0,>=2.2.1",
|
||||
"email-validator<3.0.0,>=2.1.1",
|
||||
"pydanclick<1.0.0,>=0.2.0",
|
||||
"loguru<1.0.0,>=0.7.2",
|
||||
"alembic-postgresql-enum<2.0.0,>=1.2.0",
|
||||
"gunicorn>=22.0.0",
|
||||
"uvicorn-worker>=0.2.0",
|
||||
"httpx>=0.27.0",
|
||||
"cryptography>=43.0.0",
|
||||
"python-multipart>=0.0.9",
|
||||
"jinja2>=3.1.4",
|
||||
"aiofiles>=24.1.0",
|
||||
"aioshutil>=1.5",
|
||||
"Celery>=5.4.0",
|
||||
"streaming-form-data>=1.16.0",
|
||||
]
|
||||
requires-python = ">=3.12,<3.13"
|
||||
license = {text = "MIT"}
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://materia.elnafo.ru"
|
||||
Repository = "https://github.com/L-Nafaryus/materia"
|
||||
Documentation = "https://materia.elnafo.ru/docs"
|
||||
|
||||
[project.optional-dependencies]
|
||||
docs = [
|
||||
]
|
||||
frontend = [
|
||||
#"materia-frontend>=0.1.1",
|
||||
]
|
||||
all = [
|
||||
#"materia[frontend]",
|
||||
]
|
||||
|
||||
[build-system]
|
||||
requires = ["pdm-backend"]
|
||||
build-backend = "pdm.backend"
|
||||
|
||||
[project.scripts]
|
||||
materia = "materia_server.app.cli:cli"
|
||||
|
||||
[tool.pyright]
|
||||
reportGeneralTypeIssues = false
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
pythonpath = ["."]
|
||||
testpaths = ["tests"]
|
||||
|
||||
[tool.pdm]
|
||||
distribution = true
|
||||
|
||||
[tool.pdm.dev-dependencies]
|
||||
dev = [
|
||||
"black<24.0.0,>=23.3.0",
|
||||
"pytest<8.0.0,>=7.3.2",
|
||||
"pyflakes<4.0.0,>=3.0.1",
|
||||
"pyright<2.0.0,>=1.1.314",
|
||||
"pytest-asyncio>=0.23.7",
|
||||
"asgi-lifespan>=2.1.0",
|
||||
"pytest-cov>=5.0.0",
|
||||
]
|
||||
|
||||
[tool.pdm.build]
|
||||
package-dir = "src"
|
||||
includes = ["src/materia_server"]
|
||||
|
||||
[tool.pdm.scripts]
|
||||
start.cmd = "python ./src/materia/main.py {args:start --app-mode development --log-level debug}"
|
||||
setup.cmd = "psql -U postgres -h 127.0.0.1 -p 54320 -d postgres -c 'create role materia login;' -c 'create database materia owner materia;'"
|
||||
teardown.cmd = "psql -U postgres -h 127.0.0.1 -p 54320 -d postgres -c 'drop database materia;' -c 'drop role materia;'"
|
||||
rev.cmd = "alembic revision {args:--autogenerate}"
|
||||
upgrade.cmd = "alembic upgrade {args:head}"
|
||||
downgrade.cmd = "alembic downgrade {args:base}"
|
||||
remove-revs.shell = "rm -v ./src/materia/models/migrations/versions/*.py"
|
||||
|
||||
test.cmd = "pytest"
|
||||
coverage.cmd = "pytest --cov=src/materia_server"
|
||||
|
||||
[tool.pdm.resolution]
|
||||
respect-source-order = true
|
||||
|
||||
[[tool.pdm.source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
|
||||
[[tool.pdm.source]]
|
||||
name = "elnafo-vcs"
|
||||
url = "https://vcs.elnafo.ru/api/packages/L-Nafaryus/pypi"
|
||||
verify_ssl = true
|
3
packages/server/src/materia_server/__main__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from materia_server.app import cli
|
||||
|
||||
cli()
|
2
packages/server/src/materia_server/app/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from materia_server.app.app import Context, Application
|
||||
from materia_server.app.cli import cli
|
@ -9,7 +9,7 @@ from fastapi import FastAPI
|
||||
from fastapi.routing import APIRoute
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from materia.core import (
|
||||
from materia_server.core import (
|
||||
Config,
|
||||
Logger,
|
||||
LoggerInstance,
|
||||
@ -17,8 +17,8 @@ from materia.core import (
|
||||
Cache,
|
||||
Cron,
|
||||
)
|
||||
from materia import routers
|
||||
from materia.core.misc import optional, optional_string
|
||||
from materia_server import routers
|
||||
from materia_server.core.misc import optional, optional_string
|
||||
|
||||
|
||||
class Context(TypedDict):
|
||||
@ -66,13 +66,6 @@ class Application:
|
||||
app.logger.error(" ".join(e.args))
|
||||
sys.exit()
|
||||
|
||||
try:
|
||||
import materia_frontend
|
||||
except ModuleNotFoundError:
|
||||
app.logger.warning(
|
||||
"`materia_frontend` is not installed. No user interface will be served."
|
||||
)
|
||||
|
||||
return app
|
||||
|
||||
def prepare_logger(self):
|
||||
@ -134,10 +127,25 @@ class Application:
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
self.backend.include_router(routers.docs.router)
|
||||
self.backend.include_router(routers.api.router)
|
||||
self.backend.include_router(routers.resources.router)
|
||||
self.backend.include_router(routers.root.router)
|
||||
if self.config.misc.enable_api_docs:
|
||||
self.backend.include_router(routers.api_docs.router)
|
||||
if self.config.misc.enable_docs:
|
||||
try:
|
||||
import materia_docs
|
||||
except ModuleNotFoundError:
|
||||
self.logger.error(
|
||||
"The `misc.enable_docs` option was enabled but the `materia_docs` package was not found."
|
||||
)
|
||||
self.backend.include_router(routers.docs.router)
|
||||
if self.config.misc.enable_client:
|
||||
try:
|
||||
import materia_frontend
|
||||
except ModuleNotFoundError:
|
||||
self.logger.error(
|
||||
"The `misc.enable_client` option was enabled but the `materia_frontend` package was not found."
|
||||
)
|
||||
self.backend.include_router(routers.client.router)
|
||||
|
||||
for route in self.backend.routes:
|
||||
if isinstance(route, APIRoute):
|
||||
@ -167,5 +175,5 @@ class Application:
|
||||
self.logger.info("Exiting...")
|
||||
sys.exit()
|
||||
except Exception as e:
|
||||
self.logger.error(" ".join(e.args))
|
||||
self.logger.exception(" ".join(e.args), backtrace=False)
|
||||
sys.exit()
|
@ -1,8 +1,8 @@
|
||||
from os import environ
|
||||
from pathlib import Path
|
||||
from uvicorn.workers import UvicornWorker
|
||||
from materia.config import Config
|
||||
from materia._logging import uvicorn_log_config
|
||||
from materia_server.config import Config
|
||||
from materia_server._logging import uvicorn_log_config
|
||||
|
||||
|
||||
class MateriaWorker(UvicornWorker):
|