Compare commits

...

2 Commits

163 changed files with 2511 additions and 1894 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
/result* /result*
/repl-result* /repl-result*
temp/ temp/
.tmp
dist/ dist/
/.venv /.venv

View File

@ -1 +0,0 @@
::: materia.app

View File

@ -1 +0,0 @@
::: materia.core

View File

@ -1 +0,0 @@
::: materia.models

View File

@ -1 +0,0 @@
::: materia.routers

View File

@ -1 +0,0 @@
::: materia.security

View File

@ -1 +0,0 @@
::: materia.tasks

View File

@ -207,6 +207,21 @@
"type": "github" "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": { "nixos-mailserver": {
"inputs": { "inputs": {
"blobs": "blobs", "blobs": "blobs",
@ -437,6 +452,7 @@
"inputs": { "inputs": {
"bonfire": "bonfire", "bonfire": "bonfire",
"dream2nix": "dream2nix", "dream2nix": "dream2nix",
"nix-std": "nix-std",
"nixpkgs": "nixpkgs_3" "nixpkgs": "nixpkgs_3"
} }
}, },

547
flake.nix
View File

@ -8,6 +8,7 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
bonfire.url = "github:L-Nafaryus/bonfire"; bonfire.url = "github:L-Nafaryus/bonfire";
nix-std.url = "github:chessai/nix-std";
}; };
outputs = { outputs = {
@ -15,6 +16,7 @@
nixpkgs, nixpkgs,
dream2nix, dream2nix,
bonfire, bonfire,
nix-std,
... ...
}: let }: let
system = "x86_64-linux"; system = "x86_64-linux";
@ -43,45 +45,6 @@
// {inherit meta;}; // {inherit meta;};
in { in {
packages.x86_64-linux = { 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 { materia-frontend-vue = dreamBuildPackage {
module = { module = {
lib, lib,
@ -97,11 +60,7 @@
]; ];
mkDerivation = { mkDerivation = {
src = ./workspaces/frontend; src = ./packages/frontend;
configurePhase = ''
${self.packages.x86_64-linux.materia-server}/bin/materia export openapi --path ./
npm run openapi
'';
}; };
deps = {nixpkgs, ...}: { deps = {nixpkgs, ...}: {
@ -117,7 +76,8 @@
}; };
}; };
meta = with nixpkgs.lib; { 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; license = licenses.mit;
maintainers = with bonLib.maintainers; [L-Nafaryus]; maintainers = with bonLib.maintainers; [L-Nafaryus];
broken = false; broken = false;
@ -137,70 +97,128 @@
}: { }: {
imports = [dream2nix.modules.dream2nix.WIP-python-pdm]; imports = [dream2nix.modules.dream2nix.WIP-python-pdm];
pdm.lockfile = ./workspaces/frontend/pdm.lock; pdm.lockfile = ./pdm.lock;
pdm.pyproject = ./workspaces/frontend/pyproject.toml; pdm.pyproject = ./packages/frontend/pyproject.toml;
deps = _: { deps = _: {
python = pkgs.python312; python = pkgs.python312;
}; };
mkDerivation = { mkDerivation = {
src = ./workspaces/frontend; src = ./packages/frontend;
buildInputs = [ buildInputs = [
pkgs.python312.pkgs.pdm-backend pkgs.python312.pkgs.pdm-backend
]; ];
configurePhase = '' 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; { 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; license = licenses.mit;
maintainers = with bonLib.maintainers; [L-Nafaryus]; maintainers = with bonLib.maintainers; [L-Nafaryus];
broken = false; broken = false;
}; };
}; };
materia = dreamBuildPackage { materia-server = pkgs.callPackage ({
withFrontend ? true,
withDocs ? true,
...
}:
dreamBuildPackage {
extraArgs = {
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 = ./packages/server/pyproject.toml;
deps = _: {
python = pkgs.python312;
};
mkDerivation = {
src = ./packages/server;
buildInputs = [
pkgs.python312.pkgs.pdm-backend
];
nativeBuildInputs = [
pkgs.python312.pkgs.wrapPython
];
propagatedBuildInputs =
lib.optionals withFrontend [
materia-frontend
]
++ lib.optionals withDocs [materia-docs];
};
};
meta = with nixpkgs.lib; {
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 = { extraArgs = {
inherit (self.packages.x86_64-linux) materia-frontend; materia-server = self.packages.x86_64-linux.materia-server.override {
withFrontend = false;
withDocs = false;
};
}; };
module = { module = {
config, config,
lib, lib,
dream2nix, dream2nix,
materia-frontend, materia-server,
... ...
}: { }: {
imports = [dream2nix.modules.dream2nix.WIP-python-pdm]; imports = [dream2nix.modules.dream2nix.WIP-python-pdm];
pdm.lockfile = ./pdm.lock; pdm.lockfile = ./pdm.lock;
pdm.pyproject = ./pyproject.toml; pdm.pyproject = ./packages/docs/pyproject.toml;
deps = _: { deps = _: {
python = pkgs.python312; python = pkgs.python312;
}; };
mkDerivation = { mkDerivation = {
src = ./.; src = ./packages/docs;
buildInputs = [ buildInputs = [
pkgs.python312.pkgs.pdm-backend pkgs.python312.pkgs.pdm-backend
]; ];
nativeBuildInputs = [ nativeBuildInputs = [pkgs.mkdocs materia-server];
pkgs.python312.pkgs.wrapPython configurePhase = ''
]; mkdir -p target/materia_docs
propagatedBuildInputs = [ mkdocs build
materia-frontend touch target/materia_docs/__init__.py
]; '';
}; };
}; };
meta = with nixpkgs.lib; { meta = with nixpkgs.lib; {
description = "Materia"; description = "Materia is a simple and fast cloud storage (docs)";
homepage = "https://materia.elnafo.ru";
license = licenses.mit; license = licenses.mit;
maintainers = with bonLib.maintainers; [L-Nafaryus]; maintainers = with bonLib.maintainers; [L-Nafaryus];
broken = false; broken = false;
mainProgram = "materia";
}; };
}; };
@ -224,7 +242,7 @@
pathsToLink = ["/bin" "/etc" "/"]; pathsToLink = ["/bin" "/etc" "/"];
paths = with pkgs; [ paths = with pkgs; [
bash bash
self.packages.x86_64-linux.materia self.packages.x86_64-linux.materia-server
entryPoint entryPoint
]; ];
}; };
@ -257,5 +275,406 @@
# greenlet requires libstdc++ # greenlet requires libstdc++
LD_LIBRARY_PATH = nixpkgs.lib.makeLibraryPath [pkgs.stdenv.cc.cc]; 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
View File

@ -0,0 +1 @@
/target

View File

@ -1,3 +1,6 @@
docs_dir: src
site_dir: target/materia_docs
site_name: Materia Documentation site_name: Materia Documentation
site_description: Materia cloud storage site_description: Materia cloud storage
#site_url: #site_url:
@ -53,7 +56,7 @@ plugins:
- mkdocstrings: - mkdocstrings:
handlers: handlers:
python: python:
paths: [src] # search packages in the src folder paths: [../server/src] # search packages in the src folder
options: options:
extensions: extensions:
- griffe_typingdoc - griffe_typingdoc
@ -76,18 +79,6 @@ plugins:
filters: 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: markdown_extensions:
# Python Markdown # Python Markdown
abbr: abbr:
@ -131,3 +122,20 @@ markdown_extensions:
pymdownx.blocks.details: pymdownx.blocks.details:
pymdownx.blocks.tab: pymdownx.blocks.tab:
alternate_style: True 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

View 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"

View 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*

View File

@ -0,0 +1,3 @@
# Local development
*Soon*

View File

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 129 KiB

View File

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -15,7 +15,7 @@
<strong><em>Materia is a simple and fast cloud storage</em></strong> <strong><em>Materia is a simple and fast cloud storage</em></strong>
</p> </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) **Source**: [https://vcs.elnafo.ru/L-Nafaryus/materia](https://vcs.elnafo.ru/L-Nafaryus/materia)
@ -148,4 +148,4 @@ pdm build
## License ## 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).

View File

@ -0,0 +1 @@
::: materia_server.app

View File

@ -0,0 +1 @@
::: materia_server.core

View File

@ -0,0 +1 @@
::: materia_server.models

View File

@ -0,0 +1 @@
::: materia_server.routers

View File

@ -0,0 +1 @@
::: materia_server.security

View File

@ -0,0 +1 @@
::: materia_server.tasks

View File

@ -0,0 +1 @@
# Getting started

View File

@ -11,5 +11,6 @@ node_modules/
*.mjs *.mjs
*.log *.log
openapi.json #openapi.json
/target
src/client src/client

View File

@ -2,7 +2,7 @@
<html lang="en" class="h-full"> <html lang="en" class="h-full">
<head> <head>
<meta charset="UTF-8"> <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"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Materia Dev</title> <title>Materia Dev</title>
</head> </head>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,25 @@
{ {
"name": "materia-frontend-vue", "name": "materia-frontend-vue",
"version": "0.1.1", "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, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build-check": "run-p type-check \"build-only {@}\" --", "build-check": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview", "preview": "vite preview",
"build": "vite build", "simple-build": "vite build",
"build": "npm run openapi && vite build",
"type-check": "vue-tsc --build --force", "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": { "dependencies": {
"@catppuccin/tailwindcss": "^0.1.6", "@catppuccin/tailwindcss": "^0.1.6",

View 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"

View File

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 862 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -9,7 +9,7 @@ export const is_authorized = async (): Promise<boolean> => {
.then(async res => { userStore.info = res.data; }) .then(async res => { userStore.info = res.data; })
.then(async () => { .then(async () => {
if (!userStore.avatar && userStore.info.avatar) { 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; }) .then(async res => { userStore.avatar = res.data; })
} }
}) })

View File

@ -31,7 +31,7 @@ export const useUser = defineStore("user", () => {
}) })
.then(async () => { .then(async () => {
if (!avatar.value && info.value.avatar) { 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; }) .then(async res => { avatar.value = res.data; })
} }
}) })

View File

@ -2,11 +2,11 @@
<html lang="en" class="h-full"> <html lang="en" class="h-full">
<head> <head>
<meta charset="UTF-8"> <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"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Materia</title> <title>Materia</title>
<script type="module" crossorigin src="/resources/assets/index.js"></script> <script type="module" crossorigin src="/assets/index.js"></script>
<link rel="stylesheet" crossorigin href="/resources/assets/index.css"> <link rel="stylesheet" crossorigin href="/assets/index.css">
</head> </head>
<body class="h-full bg-zinc-900 text-zinc-200 font-sans"> <body class="h-full bg-zinc-900 text-zinc-200 font-sans">
<div id="{{ view }}" class="flex flex-col h-full"></div> <div id="{{ view }}" class="flex flex-col h-full"></div>

View File

@ -10,12 +10,11 @@ export default defineConfig({
vueJsx(), vueJsx(),
], ],
build: { build: {
//outDir: path.resolve(__dirname, "./frontend"),
rollupOptions: { rollupOptions: {
output: { output: {
entryFileNames: "resources/assets/[name].js", entryFileNames: "assets/[name].js",
assetFileNames: "resources/assets/[name][extname]", assetFileNames: "assets/[name][extname]",
chunkFileNames: "resources/assets/[name].js" chunkFileNames: "assets/[name].js"
} }
} }
}, },

18
packages/server/.gitignore vendored Normal file
View 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

View 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

View File

@ -0,0 +1,3 @@
from materia_server.app import cli
cli()

View File

@ -0,0 +1,2 @@
from materia_server.app.app import Context, Application
from materia_server.app.cli import cli

View File

@ -9,7 +9,7 @@ from fastapi import FastAPI
from fastapi.routing import APIRoute from fastapi.routing import APIRoute
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from materia.core import ( from materia_server.core import (
Config, Config,
Logger, Logger,
LoggerInstance, LoggerInstance,
@ -17,8 +17,8 @@ from materia.core import (
Cache, Cache,
Cron, Cron,
) )
from materia import routers from materia_server import routers
from materia.core.misc import optional, optional_string from materia_server.core.misc import optional, optional_string
class Context(TypedDict): class Context(TypedDict):
@ -66,13 +66,6 @@ class Application:
app.logger.error(" ".join(e.args)) app.logger.error(" ".join(e.args))
sys.exit() sys.exit()
try:
import materia_frontend
except ModuleNotFoundError:
app.logger.warning(
"`materia_frontend` is not installed. No user interface will be served."
)
return app return app
def prepare_logger(self): def prepare_logger(self):
@ -134,10 +127,25 @@ class Application:
allow_methods=["*"], allow_methods=["*"],
allow_headers=["*"], allow_headers=["*"],
) )
self.backend.include_router(routers.docs.router)
self.backend.include_router(routers.api.router) self.backend.include_router(routers.api.router)
self.backend.include_router(routers.resources.router) if self.config.misc.enable_api_docs:
self.backend.include_router(routers.root.router) 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: for route in self.backend.routes:
if isinstance(route, APIRoute): if isinstance(route, APIRoute):
@ -167,5 +175,5 @@ class Application:
self.logger.info("Exiting...") self.logger.info("Exiting...")
sys.exit() sys.exit()
except Exception as e: except Exception as e:
self.logger.error(" ".join(e.args)) self.logger.exception(" ".join(e.args), backtrace=False)
sys.exit() sys.exit()

View File

@ -1,8 +1,8 @@
from os import environ from os import environ
from pathlib import Path from pathlib import Path
from uvicorn.workers import UvicornWorker from uvicorn.workers import UvicornWorker
from materia.config import Config from materia_server.config import Config
from materia._logging import uvicorn_log_config from materia_server._logging import uvicorn_log_config
class MateriaWorker(UvicornWorker): class MateriaWorker(UvicornWorker):

Some files were not shown because too many files have changed in this diff Show More