WIP: Add indico profile + required packages
Signed-off-by: Jeltz <jeltz@federez.net>
This commit is contained in:
parent
bb03bd9054
commit
d12f9d91d1
17 changed files with 1377 additions and 90 deletions
1
hive.nix
1
hive.nix
|
@ -165,6 +165,7 @@ in
|
||||||
|
|
||||||
imports = [
|
imports = [
|
||||||
./profiles/vm.nix
|
./profiles/vm.nix
|
||||||
|
./profiles/indico.nix
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
57
pkgs/flask-multipass/default.nix
Normal file
57
pkgs/flask-multipass/default.nix
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
hatchling,
|
||||||
|
flask,
|
||||||
|
blinker,
|
||||||
|
authlib,
|
||||||
|
requests,
|
||||||
|
flask-wtf,
|
||||||
|
python-ldap,
|
||||||
|
python3-saml,
|
||||||
|
sqlalchemy,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "flask-multipass";
|
||||||
|
version = "0.6";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "indico";
|
||||||
|
repo = "flask-multipass";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-1SfyCpa1j7a1emhruVLBtXwDr6BisnvUnTA1ioQmGzQ=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [ hatchling ];
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
flask
|
||||||
|
blinker
|
||||||
|
];
|
||||||
|
|
||||||
|
optional-dependencies = {
|
||||||
|
authlib = [
|
||||||
|
authlib
|
||||||
|
requests
|
||||||
|
];
|
||||||
|
ldap = [
|
||||||
|
flask-wtf
|
||||||
|
python-ldap
|
||||||
|
];
|
||||||
|
saml = [ python3-saml ];
|
||||||
|
sqlalchemy = [
|
||||||
|
sqlalchemy
|
||||||
|
flask-wtf
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "A pluggable solution for multi-backend authentication with Flask";
|
||||||
|
homepage = "https://github.com/indico/flask-multipass";
|
||||||
|
changelog = "https://github.com/indico/flask-multipass/blob/${version}/CHANGES.rst";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
41
pkgs/flask-pluginengine/default.nix
Normal file
41
pkgs/flask-pluginengine/default.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
flask,
|
||||||
|
jinja2,
|
||||||
|
blinker,
|
||||||
|
importlib-metadata,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "flask-pluginengine";
|
||||||
|
version = "0.5";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "indico";
|
||||||
|
repo = "flask-pluginengine";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-O41z1GYA4pau6UP2rw4aU4SMr3sXsn4yd+yMvVNwT0k=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [ setuptools ];
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
flask
|
||||||
|
jinja2
|
||||||
|
blinker
|
||||||
|
importlib-metadata
|
||||||
|
];
|
||||||
|
|
||||||
|
pythonImportChecks = [ "flask_pluginengine" ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "A simple plugin system for Flask applications";
|
||||||
|
homepage = "https://github.com/indico/flask-pluginengine";
|
||||||
|
changelog = "https://github.com/indico/flask-pluginengine/blob/${version}/CHANGES.rst";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
41
pkgs/flask-webpackext/default.nix
Normal file
41
pkgs/flask-webpackext/default.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
wheel,
|
||||||
|
babel,
|
||||||
|
flask,
|
||||||
|
pywebpack,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "flask-webpackext";
|
||||||
|
version = "2.0.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "inveniosoftware";
|
||||||
|
repo = "flask-webpackext";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-jGYUsmj52dsu9hR4TEDVt/jX3mt5ForYbhwi2t4DaRw=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [
|
||||||
|
setuptools
|
||||||
|
wheel
|
||||||
|
babel
|
||||||
|
];
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
flask
|
||||||
|
pywebpack
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Webpack integration for Flask";
|
||||||
|
homepage = "https://github.com/inveniosoftware/flask-webpackext";
|
||||||
|
changelog = "https://github.com/inveniosoftware/flask-webpackext/blob/${version}/CHANGES.rst";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
31
pkgs/indico-fonts/default.nix
Normal file
31
pkgs/indico-fonts/default.nix
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "indico-fonts";
|
||||||
|
version = "1.2";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "indico";
|
||||||
|
repo = "indico-fonts";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-tqpsmthcg9BXxoM/cii+dtXzw0vgu8sek/F1cVNTu+8=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [ setuptools ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Indico binary fonts";
|
||||||
|
homepage = "https://github.com/indico/indico-fonts";
|
||||||
|
license = [
|
||||||
|
lib.licenses.ofl
|
||||||
|
lib.licenses.arphicpl
|
||||||
|
# TODO indico_fonts/LICENSE-efont
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
174
pkgs/indico/default.nix
Normal file
174
pkgs/indico/default.nix
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
fetchPypi,
|
||||||
|
python3,
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
python = python3.override {
|
||||||
|
self = python;
|
||||||
|
packageOverrides = self: super: {
|
||||||
|
celery = super.celery.overridePythonAttrs rec {
|
||||||
|
optional-dependencies.redis = [ self.redis ];
|
||||||
|
};
|
||||||
|
# Version 3.0.5 is the last one to support SQLAlchemy 1.4
|
||||||
|
flask-multipass = self.callPackage ../flask-multipass { };
|
||||||
|
flask-pluginengine = self.callPackage ../flask-pluginengine { };
|
||||||
|
flask-sqlalchemy = super.flask-sqlalchemy.overridePythonAttrs rec {
|
||||||
|
version = "3.0.5";
|
||||||
|
src = fetchPypi {
|
||||||
|
pname = "flask_sqlalchemy";
|
||||||
|
inherit version;
|
||||||
|
hash = "sha256-xXZeWMoUVAG1IQbA9GF4VpJDxdolVWviwjHsxghnxbE=";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
flask-webpackext = self.callPackage ../flask-webpackext { };
|
||||||
|
indico-fonts = self.callPackage ../indico-fonts { };
|
||||||
|
lxml = super.lxml.overridePythonAttrs rec {
|
||||||
|
optional-dependencies.html5 = [ self.html5lib ];
|
||||||
|
};
|
||||||
|
pynpm = self.callPackage ../pynpm { };
|
||||||
|
pywebpack = self.callPackage ../pywebpack { };
|
||||||
|
sentry-sdk = super.sentry-sdk_1;
|
||||||
|
sqlalchemy = super.sqlalchemy_1_4;
|
||||||
|
wtforms-dateutil = self.callPackage ../wtforms-dateutil { };
|
||||||
|
wtforms-sqlalchemy = self.callPackage ../wtforms-sqlalchemy { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
python.pkgs.buildPythonApplication rec {
|
||||||
|
pname = "indico";
|
||||||
|
version = "3.3.5";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
disabled = python.pkgs.pythonOlder "3.12";
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "indico";
|
||||||
|
repo = "indico";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-OX5tqeIjd7Lb5XfvFFKcYb9Dbf5Z9QLXlVTepTpeOMU=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = with python.pkgs; [
|
||||||
|
hatchling
|
||||||
|
hatch-requirements-txt
|
||||||
|
];
|
||||||
|
|
||||||
|
patches = [
|
||||||
|
./remove_marshmallow_enum.patch
|
||||||
|
];
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
# See JoshData/python-email-validator#90
|
||||||
|
substituteInPlace requirements.in \
|
||||||
|
--replace "email-validator<1.3.0" "email-validator!=1.3.0"
|
||||||
|
# Botocore doesn't seem to be used anymore
|
||||||
|
substituteInPlace requirements.in --replace "urllib3<2" "urllib3"
|
||||||
|
# Seems fixed
|
||||||
|
substituteInPlace requirements.in --replace "pydyf<0.10" "pydyf"
|
||||||
|
# Remove transitive dependencies and unnecessary version pins
|
||||||
|
cp requirements.in requirements.txt
|
||||||
|
'';
|
||||||
|
|
||||||
|
dependencies =
|
||||||
|
with python.pkgs;
|
||||||
|
[
|
||||||
|
alembic
|
||||||
|
authlib
|
||||||
|
babel
|
||||||
|
bcrypt
|
||||||
|
bleach
|
||||||
|
blinker
|
||||||
|
captcha
|
||||||
|
celery
|
||||||
|
certifi
|
||||||
|
click
|
||||||
|
colorclass
|
||||||
|
distro
|
||||||
|
email-validator
|
||||||
|
feedgen
|
||||||
|
flask-babel
|
||||||
|
flask-caching
|
||||||
|
flask-cors
|
||||||
|
flask-limiter
|
||||||
|
flask-marshmallow
|
||||||
|
flask-migrate
|
||||||
|
flask-multipass
|
||||||
|
flask-pluginengine
|
||||||
|
flask-sqlalchemy
|
||||||
|
flask-webpackext
|
||||||
|
flask-wtf
|
||||||
|
flask
|
||||||
|
google-auth
|
||||||
|
hiredis
|
||||||
|
html2text
|
||||||
|
icalendar
|
||||||
|
indico-fonts
|
||||||
|
ipython
|
||||||
|
itsdangerous
|
||||||
|
jinja2
|
||||||
|
jsonschema
|
||||||
|
lxml
|
||||||
|
markdown
|
||||||
|
markupsafe
|
||||||
|
marshmallow-dataclass
|
||||||
|
marshmallow-oneofschema
|
||||||
|
marshmallow-sqlalchemy
|
||||||
|
marshmallow
|
||||||
|
packaging
|
||||||
|
pillow
|
||||||
|
prompt-toolkit
|
||||||
|
psycopg2
|
||||||
|
pycountry
|
||||||
|
pydyf
|
||||||
|
pygments
|
||||||
|
pypdf
|
||||||
|
python-dateutil
|
||||||
|
pytz
|
||||||
|
pywebpack
|
||||||
|
pyyaml
|
||||||
|
qrcode
|
||||||
|
redis
|
||||||
|
reportlab
|
||||||
|
requests
|
||||||
|
sentry-sdk
|
||||||
|
simplejson
|
||||||
|
speaklater
|
||||||
|
sqlalchemy
|
||||||
|
terminaltables
|
||||||
|
translitcodec
|
||||||
|
ua-parser
|
||||||
|
urllib3
|
||||||
|
wallet-py3k
|
||||||
|
weasyprint
|
||||||
|
webargs
|
||||||
|
werkzeug
|
||||||
|
wtforms
|
||||||
|
wtforms-dateutil
|
||||||
|
wtforms-sqlalchemy
|
||||||
|
xlsxwriter
|
||||||
|
]
|
||||||
|
++ bleach.optional-dependencies.css
|
||||||
|
++ celery.optional-dependencies.redis
|
||||||
|
++ qrcode.optional-dependencies.pil
|
||||||
|
++ lxml.optional-dependencies.html5
|
||||||
|
++ redis.optional-dependencies.hiredis
|
||||||
|
++ sentry-sdk_1.optional-dependencies.flask
|
||||||
|
++ sentry-sdk_1.optional-dependencies.celery
|
||||||
|
++ sentry-sdk_1.optional-dependencies.sqlalchemy
|
||||||
|
++ sentry-sdk_1.optional-dependencies.pure_eval
|
||||||
|
++ wtforms.optional-dependencies.email;
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
inherit python;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Full-featured conferency lifecycle management and meeting/lecture scheduling tool";
|
||||||
|
homepage = "https://getindico.io/";
|
||||||
|
changelog = "https://docs.getindico.io/en/stable/changelog/";
|
||||||
|
license = lib.licenses.mit;
|
||||||
|
};
|
||||||
|
}
|
678
pkgs/indico/remove_marshmallow_enum.patch
Normal file
678
pkgs/indico/remove_marshmallow_enum.patch
Normal file
|
@ -0,0 +1,678 @@
|
||||||
|
diff --git a/indico/core/marshmallow.py b/indico/core/marshmallow.py
|
||||||
|
index d3718a5..e51ba0a 100644
|
||||||
|
--- a/indico/core/marshmallow.py
|
||||||
|
+++ b/indico/core/marshmallow.py
|
||||||
|
@@ -10,7 +10,6 @@ from inspect import getmro
|
||||||
|
from flask_marshmallow import Marshmallow
|
||||||
|
from flask_marshmallow.sqla import SQLAlchemyAutoSchemaOpts
|
||||||
|
from marshmallow import fields, post_dump, post_load, pre_load
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from marshmallow_sqlalchemy import ModelConverter
|
||||||
|
from marshmallow_sqlalchemy import SQLAlchemyAutoSchema as MSQLASQLAlchemyAutoSchema
|
||||||
|
from sqlalchemy.orm import ColumnProperty
|
||||||
|
@@ -33,7 +32,7 @@ class IndicoModelConverter(ModelConverter):
|
||||||
|
SQLA_TYPE_MAPPING = ModelConverter.SQLA_TYPE_MAPPING.copy()
|
||||||
|
SQLA_TYPE_MAPPING.update({
|
||||||
|
UTCDateTime: fields.DateTime,
|
||||||
|
- PyIntEnum: EnumField
|
||||||
|
+ PyIntEnum: fields.Enum
|
||||||
|
})
|
||||||
|
|
||||||
|
def _get_field_kwargs_for_property(self, prop):
|
||||||
|
diff --git a/indico/modules/categories/controllers/display.py b/indico/modules/categories/controllers/display.py
|
||||||
|
index 00d229c..b2e0707 100644
|
||||||
|
--- a/indico/modules/categories/controllers/display.py
|
||||||
|
+++ b/indico/modules/categories/controllers/display.py
|
||||||
|
@@ -17,7 +17,6 @@ import dateutil
|
||||||
|
from dateutil.parser import ParserError
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from flask import flash, jsonify, redirect, request, session
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from pytz import utc
|
||||||
|
from sqlalchemy.orm import joinedload, load_only, selectinload, subqueryload, undefer, undefer_group
|
||||||
|
from webargs import fields, validate
|
||||||
|
@@ -575,7 +574,7 @@ class RHCategoryCalendarViewEvents(RHDisplayCategoryBase):
|
||||||
|
room = auto()
|
||||||
|
keywords = auto()
|
||||||
|
|
||||||
|
- @use_kwargs({'group_by': EnumField(GroupBy, load_default=GroupBy.category)}, location='query')
|
||||||
|
+ @use_kwargs({'group_by': fields.Enum(GroupBy, load_default=GroupBy.category)}, location='query')
|
||||||
|
def _process_args(self, group_by):
|
||||||
|
RHDisplayCategoryBase._process_args(self)
|
||||||
|
tz = self.category.display_tzinfo
|
||||||
|
diff --git a/indico/modules/events/contributions/schemas.py b/indico/modules/events/contributions/schemas.py
|
||||||
|
index 3ea9d17..0f1df57 100644
|
||||||
|
--- a/indico/modules/events/contributions/schemas.py
|
||||||
|
+++ b/indico/modules/events/contributions/schemas.py
|
||||||
|
@@ -9,7 +9,6 @@ import hashlib
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
|
from marshmallow import fields, post_dump
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from marshmallow_sqlalchemy import column2field
|
||||||
|
|
||||||
|
from indico.core.marshmallow import mm
|
||||||
|
@@ -38,7 +37,7 @@ class ContributionTypeSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
|
||||||
|
|
||||||
|
class ContributionFieldSchema(mm.Schema):
|
||||||
|
- visibility = EnumField(ContributionFieldVisibility)
|
||||||
|
+ visibility = fields.Enum(ContributionFieldVisibility)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = ContributionField
|
||||||
|
diff --git a/indico/modules/events/controllers/display.py b/indico/modules/events/controllers/display.py
|
||||||
|
index e7d4830..eb4aa57 100644
|
||||||
|
--- a/indico/modules/events/controllers/display.py
|
||||||
|
+++ b/indico/modules/events/controllers/display.py
|
||||||
|
@@ -8,7 +8,6 @@
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
from flask import jsonify, redirect, request, session
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from webargs import fields
|
||||||
|
|
||||||
|
from indico.modules.events.controllers.base import RHDisplayEventBase, RHEventBase
|
||||||
|
@@ -27,7 +26,7 @@ from indico.web.rh import RHProtected, allow_signed_url
|
||||||
|
@allow_signed_url
|
||||||
|
class RHExportEventICAL(RHDisplayEventBase):
|
||||||
|
@use_kwargs({
|
||||||
|
- 'scope': EnumField(CalendarScope, load_default=None),
|
||||||
|
+ 'scope': fields.Enum(CalendarScope, load_default=None),
|
||||||
|
'detail': fields.String(load_default=None),
|
||||||
|
'series': fields.Boolean(load_default=False) # Export the full event series
|
||||||
|
}, location='query')
|
||||||
|
diff --git a/indico/modules/events/editing/controllers/backend/timeline.py b/indico/modules/events/editing/controllers/backend/timeline.py
|
||||||
|
index 1088178..4c9a807 100644
|
||||||
|
--- a/indico/modules/events/editing/controllers/backend/timeline.py
|
||||||
|
+++ b/indico/modules/events/editing/controllers/backend/timeline.py
|
||||||
|
@@ -13,7 +13,6 @@ from zipfile import ZipFile, ZipInfo
|
||||||
|
|
||||||
|
from flask import jsonify, request, session
|
||||||
|
from marshmallow import EXCLUDE, fields
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from sqlalchemy.orm import joinedload
|
||||||
|
from werkzeug.exceptions import BadRequest, Conflict, Forbidden, NotFound, ServiceUnavailable
|
||||||
|
|
||||||
|
@@ -248,7 +247,7 @@ class RHConfirmEditableChanges(RHContributionEditableRevisionBase):
|
||||||
|
return self.editable.can_perform_submitter_actions(session.user)
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
- 'action': EnumField(EditingConfirmationAction, required=True),
|
||||||
|
+ 'action': fields.Enum(EditingConfirmationAction, required=True),
|
||||||
|
'comment': fields.String(load_default='')
|
||||||
|
})
|
||||||
|
def _process(self, action, comment):
|
||||||
|
@@ -267,7 +266,7 @@ class RHReplaceRevision(RHContributionEditableRevisionBase):
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
'comment': fields.String(load_default=''),
|
||||||
|
- 'revision_type': EnumField(RevisionType)
|
||||||
|
+ 'revision_type': fields.Enum(RevisionType)
|
||||||
|
})
|
||||||
|
def _process(self, comment, revision_type):
|
||||||
|
args = parser.parse({
|
||||||
|
diff --git a/indico/modules/events/editing/schemas.py b/indico/modules/events/editing/schemas.py
|
||||||
|
index f3c022e..b5da577 100644
|
||||||
|
--- a/indico/modules/events/editing/schemas.py
|
||||||
|
+++ b/indico/modules/events/editing/schemas.py
|
||||||
|
@@ -10,7 +10,6 @@ from operator import itemgetter
|
||||||
|
|
||||||
|
from markupsafe import escape
|
||||||
|
from marshmallow import ValidationError, fields, post_dump, validate, validates, validates_schema
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from sqlalchemy import func
|
||||||
|
|
||||||
|
from indico.core.marshmallow import mm
|
||||||
|
@@ -251,7 +250,7 @@ class EditableBasicSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
model = Editable
|
||||||
|
fields = ('id', 'type', 'state', 'editor', 'timeline_url', 'revision_count', 'tags', 'last_update_dt')
|
||||||
|
|
||||||
|
- state = EnumField(EditableState)
|
||||||
|
+ state = fields.Enum(EditableState)
|
||||||
|
editor = fields.Nested(EditingUserSchema)
|
||||||
|
timeline_url = fields.String()
|
||||||
|
tags = fields.List(fields.Nested(EditingTagSchema, only=('id', 'code', 'title', 'color')),
|
||||||
|
@@ -295,7 +294,7 @@ class FilteredEditableSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
attribute='contribution.person_links')
|
||||||
|
contribution_keywords = fields.List(fields.String(), attribute='contribution.keywords')
|
||||||
|
contribution_session = fields.Nested(SessionBasicSchema, attribute='contribution.session')
|
||||||
|
- state = EnumField(EditableState)
|
||||||
|
+ state = fields.Enum(EditableState)
|
||||||
|
timeline_url = fields.String()
|
||||||
|
editor = fields.Nested(EditingUserSchema)
|
||||||
|
can_assign_self = fields.Function(lambda editable, ctx: editable.can_assign_self(ctx.get('user')))
|
||||||
|
@@ -318,7 +317,7 @@ class EditingReviewAction(IndicoEnum):
|
||||||
|
|
||||||
|
|
||||||
|
class ReviewEditableArgs(mm.Schema):
|
||||||
|
- action = EnumField(EditingReviewAction, required=True)
|
||||||
|
+ action = fields.Enum(EditingReviewAction, required=True)
|
||||||
|
comment = fields.String(load_default='')
|
||||||
|
|
||||||
|
@validates_schema(skip_on_field_errors=True)
|
||||||
|
@@ -437,7 +436,7 @@ class EditingMenuItemSchema(mm.Schema):
|
||||||
|
|
||||||
|
|
||||||
|
class EditableTypeArgs(mm.Schema):
|
||||||
|
- editable_types = fields.List(EnumField(EditableType), required=True)
|
||||||
|
+ editable_types = fields.List(fields.Enum(EditableType), required=True)
|
||||||
|
|
||||||
|
|
||||||
|
class EditableTypePrincipalsSchema(mm.Schema):
|
||||||
|
diff --git a/indico/modules/events/notes/controllers.py b/indico/modules/events/notes/controllers.py
|
||||||
|
index 4e8a17e..c5b3191 100644
|
||||||
|
--- a/indico/modules/events/notes/controllers.py
|
||||||
|
+++ b/indico/modules/events/notes/controllers.py
|
||||||
|
@@ -6,7 +6,6 @@
|
||||||
|
# LICENSE file for more details.
|
||||||
|
|
||||||
|
from flask import jsonify, redirect, request, session
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from webargs import fields
|
||||||
|
from werkzeug.exceptions import Forbidden, NotFound
|
||||||
|
|
||||||
|
@@ -70,7 +69,7 @@ class RHApiNote(RHManageNoteBase):
|
||||||
|
return EventNoteSchema().dump(note.current_revision)
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
- 'render_mode': EnumField(RenderMode, load_default=RenderMode.html),
|
||||||
|
+ 'render_mode': fields.Enum(RenderMode, load_default=RenderMode.html),
|
||||||
|
'source': fields.String(required=True),
|
||||||
|
'revision_id': fields.Integer(),
|
||||||
|
})
|
||||||
|
diff --git a/indico/modules/events/papers/controllers/api.py b/indico/modules/events/papers/controllers/api.py
|
||||||
|
index c06042c..183bc7f 100644
|
||||||
|
--- a/indico/modules/events/papers/controllers/api.py
|
||||||
|
+++ b/indico/modules/events/papers/controllers/api.py
|
||||||
|
@@ -6,7 +6,6 @@
|
||||||
|
# LICENSE file for more details.
|
||||||
|
|
||||||
|
from flask import request, session
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from webargs import fields, validate
|
||||||
|
from werkzeug.exceptions import Forbidden, UnprocessableEntity
|
||||||
|
|
||||||
|
@@ -50,7 +49,7 @@ class RHCreatePaperComment(RHPaperBase):
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
'comment': fields.String(validate=not_empty),
|
||||||
|
- 'visibility': EnumField(PaperCommentVisibility, load_default=None)
|
||||||
|
+ 'visibility': fields.Enum(PaperCommentVisibility, load_default=None)
|
||||||
|
})
|
||||||
|
def _process(self, comment, visibility):
|
||||||
|
create_comment(self.paper, comment, visibility, session.user)
|
||||||
|
@@ -82,7 +81,7 @@ class RHCommentActions(RHPaperBase):
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
'comment': fields.String(validate=not_empty),
|
||||||
|
- 'visibility': EnumField(PaperCommentVisibility)
|
||||||
|
+ 'visibility': fields.Enum(PaperCommentVisibility)
|
||||||
|
}, partial=True)
|
||||||
|
def _process_PATCH(self, comment=None, visibility=None):
|
||||||
|
update_comment(self.comment, comment, visibility)
|
||||||
|
@@ -94,7 +93,7 @@ class RHJudgePaper(RHPaperBase):
|
||||||
|
return self.paper.can_judge(session.user, check_state=True)
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
- 'action': EnumField(PaperAction, required=True),
|
||||||
|
+ 'action': fields.Enum(PaperAction, required=True),
|
||||||
|
'comment': fields.String()
|
||||||
|
})
|
||||||
|
def _process(self, action, comment):
|
||||||
|
@@ -122,7 +121,7 @@ class RHSubmitNewRevision(RHPaperBase):
|
||||||
|
|
||||||
|
def _parse_review_args(event, review_type):
|
||||||
|
args_schema = {
|
||||||
|
- 'proposed_action': EnumField(PaperAction, required=True),
|
||||||
|
+ 'proposed_action': fields.Enum(PaperAction, required=True),
|
||||||
|
'comment': fields.String(load_default='')
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/indico/modules/events/papers/schemas.py b/indico/modules/events/papers/schemas.py
|
||||||
|
index 4b228ab..fd47bcf 100644
|
||||||
|
--- a/indico/modules/events/papers/schemas.py
|
||||||
|
+++ b/indico/modules/events/papers/schemas.py
|
||||||
|
@@ -7,8 +7,7 @@
|
||||||
|
|
||||||
|
from markupsafe import escape
|
||||||
|
from marshmallow import post_dump
|
||||||
|
-from marshmallow.fields import Boolean, Decimal, Field, Function, Integer, List, Method, Nested, String
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
+from marshmallow.fields import Boolean, Decimal, Enum, Field, Function, Integer, List, Method, Nested, String
|
||||||
|
|
||||||
|
from indico.core.marshmallow import mm
|
||||||
|
from indico.modules.events.contributions.schemas import BasicContributionSchema
|
||||||
|
@@ -100,7 +99,7 @@ class PaperRevisionSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
judge = Nested(BasicUserSchema)
|
||||||
|
spotlight_file = Nested(PaperFileSchema)
|
||||||
|
files = List(Nested(PaperFileSchema))
|
||||||
|
- state = EnumField(PaperRevisionState)
|
||||||
|
+ state = Enum(PaperRevisionState)
|
||||||
|
timeline = PaperRevisionTimelineField()
|
||||||
|
judgment_comment_html = Function(lambda revision: escape(revision.judgment_comment))
|
||||||
|
reviewer_data = Method('_get_reviewer_data')
|
||||||
|
diff --git a/indico/modules/events/persons/schemas.py b/indico/modules/events/persons/schemas.py
|
||||||
|
index 9de1947..f122ae1 100644
|
||||||
|
--- a/indico/modules/events/persons/schemas.py
|
||||||
|
+++ b/indico/modules/events/persons/schemas.py
|
||||||
|
@@ -6,7 +6,6 @@
|
||||||
|
# LICENSE file for more details.
|
||||||
|
|
||||||
|
from marshmallow import fields, post_dump, post_load, pre_load
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
|
||||||
|
from indico.core.marshmallow import mm
|
||||||
|
from indico.modules.events.models.persons import EventPerson
|
||||||
|
@@ -24,7 +23,7 @@ class PersonLinkSchema(mm.Schema):
|
||||||
|
name = fields.String(attribute='display_full_name', dump_only=True)
|
||||||
|
first_name = fields.String(load_default='')
|
||||||
|
last_name = fields.String(required=True)
|
||||||
|
- _title = EnumField(UserTitle, data_key='title')
|
||||||
|
+ _title = fields.Enum(UserTitle, data_key='title')
|
||||||
|
affiliation = fields.String(load_default='')
|
||||||
|
affiliation_link = ModelField(Affiliation, data_key='affiliation_id', load_default=None, load_only=True)
|
||||||
|
affiliation_id = fields.Integer(load_default=None, dump_only=True)
|
||||||
|
@@ -100,4 +99,4 @@ class EventPersonUpdateSchema(EventPersonSchema):
|
||||||
|
class Meta(EventPersonSchema.Meta):
|
||||||
|
fields = ('title', 'first_name', 'last_name', 'address', 'phone', 'affiliation', 'affiliation_link')
|
||||||
|
|
||||||
|
- title = EnumField(UserTitle)
|
||||||
|
+ title = fields.Enum(UserTitle)
|
||||||
|
diff --git a/indico/modules/events/registration/controllers/management/privacy.py b/indico/modules/events/registration/controllers/management/privacy.py
|
||||||
|
index eabbe3b..4bbd6f0 100644
|
||||||
|
--- a/indico/modules/events/registration/controllers/management/privacy.py
|
||||||
|
+++ b/indico/modules/events/registration/controllers/management/privacy.py
|
||||||
|
@@ -7,7 +7,7 @@
|
||||||
|
|
||||||
|
from flask import redirect, session
|
||||||
|
from flask.helpers import flash
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
+from marshmallow import fields
|
||||||
|
|
||||||
|
from indico.core.db import db
|
||||||
|
from indico.modules.events import EventLogRealm
|
||||||
|
@@ -64,7 +64,7 @@ class RHRegistrationPrivacy(RHManageRegFormBase):
|
||||||
|
class RHAPIRegistrationChangeConsent(RHRegistrationFormRegistrationBase):
|
||||||
|
"""Internal API to change registration consent to publish."""
|
||||||
|
|
||||||
|
- @use_kwargs({'consent_to_publish': EnumField(RegistrationVisibility)})
|
||||||
|
+ @use_kwargs({'consent_to_publish': fields.Enum(RegistrationVisibility)})
|
||||||
|
def _process_POST(self, consent_to_publish):
|
||||||
|
update_registration_consent_to_publish(self.registration, consent_to_publish)
|
||||||
|
return '', 204
|
||||||
|
diff --git a/indico/modules/events/registration/util.py b/indico/modules/events/registration/util.py
|
||||||
|
index c370676..ea03684 100644
|
||||||
|
--- a/indico/modules/events/registration/util.py
|
||||||
|
+++ b/indico/modules/events/registration/util.py
|
||||||
|
@@ -15,7 +15,6 @@ from operator import attrgetter
|
||||||
|
|
||||||
|
from flask import json, session
|
||||||
|
from marshmallow import RAISE, ValidationError, fields, validates
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from PIL import Image, ImageOps
|
||||||
|
from qrcode import QRCode, constants
|
||||||
|
from sqlalchemy import and_, or_
|
||||||
|
@@ -349,7 +348,7 @@ def make_registration_schema(
|
||||||
|
schema['notify_user'] = fields.Boolean()
|
||||||
|
schema['override_required'] = fields.Boolean()
|
||||||
|
elif regform.needs_publish_consent:
|
||||||
|
- schema['consent_to_publish'] = EnumField(RegistrationVisibility)
|
||||||
|
+ schema['consent_to_publish'] = fields.Enum(RegistrationVisibility)
|
||||||
|
|
||||||
|
if captcha_required:
|
||||||
|
schema['captcha'] = CaptchaField()
|
||||||
|
diff --git a/indico/modules/rb/controllers/backend/bookings.py b/indico/modules/rb/controllers/backend/bookings.py
|
||||||
|
index 30f95dd..c361b68 100644
|
||||||
|
--- a/indico/modules/rb/controllers/backend/bookings.py
|
||||||
|
+++ b/indico/modules/rb/controllers/backend/bookings.py
|
||||||
|
@@ -11,7 +11,6 @@ from datetime import date, datetime, time
|
||||||
|
import dateutil
|
||||||
|
from flask import jsonify, request, session
|
||||||
|
from marshmallow import fields, validate
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from sqlalchemy.orm import joinedload
|
||||||
|
from werkzeug.exceptions import BadRequest, Forbidden, NotFound
|
||||||
|
|
||||||
|
@@ -65,7 +64,7 @@ class RHTimeline(RHRoomBookingBase):
|
||||||
|
@use_kwargs({
|
||||||
|
'start_dt': fields.DateTime(required=True),
|
||||||
|
'end_dt': fields.DateTime(required=True),
|
||||||
|
- 'repeat_frequency': EnumField(RepeatFrequency, load_default='NEVER'),
|
||||||
|
+ 'repeat_frequency': fields.Enum(RepeatFrequency, load_default='NEVER'),
|
||||||
|
'repeat_interval': fields.Int(load_default=1),
|
||||||
|
'recurrence_weekdays': fields.List(fields.Str(validate=validate.OneOf(WEEKDAYS)), load_default=None),
|
||||||
|
'skip_conflicts_with': fields.List(fields.Int(), load_default=None),
|
||||||
|
@@ -311,7 +310,7 @@ class RHBookingEditCalendars(RHBookingBase):
|
||||||
|
@use_kwargs({
|
||||||
|
'start_dt': fields.DateTime(required=True),
|
||||||
|
'end_dt': fields.DateTime(required=True),
|
||||||
|
- 'repeat_frequency': EnumField(RepeatFrequency, load_default='NEVER'),
|
||||||
|
+ 'repeat_frequency': fields.Enum(RepeatFrequency, load_default='NEVER'),
|
||||||
|
'repeat_interval': fields.Int(load_default=1),
|
||||||
|
'recurrence_weekdays': fields.List(fields.Str(validate=validate.OneOf(WEEKDAYS)), load_default=None)
|
||||||
|
}, location='query')
|
||||||
|
@@ -395,7 +394,7 @@ class RHMatchingEvents(RHRoomBookingBase):
|
||||||
|
@use_kwargs({
|
||||||
|
'start_dt': fields.DateTime(),
|
||||||
|
'end_dt': fields.DateTime(),
|
||||||
|
- 'repeat_frequency': EnumField(RepeatFrequency, load_default='NEVER'),
|
||||||
|
+ 'repeat_frequency': fields.Enum(RepeatFrequency, load_default='NEVER'),
|
||||||
|
'repeat_interval': fields.Int(load_default=1),
|
||||||
|
'recurrence_weekdays': fields.List(fields.Str(validate=validate.OneOf(WEEKDAYS)), load_default=None)
|
||||||
|
}, location='query')
|
||||||
|
diff --git a/indico/modules/rb/controllers/backend/common.py b/indico/modules/rb/controllers/backend/common.py
|
||||||
|
index 5387c4f..38ecc9e 100644
|
||||||
|
--- a/indico/modules/rb/controllers/backend/common.py
|
||||||
|
+++ b/indico/modules/rb/controllers/backend/common.py
|
||||||
|
@@ -6,7 +6,6 @@
|
||||||
|
# LICENSE file for more details.
|
||||||
|
|
||||||
|
from marshmallow import validate
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from webargs import fields
|
||||||
|
|
||||||
|
from indico.modules.rb.models.reservations import RepeatFrequency
|
||||||
|
@@ -23,7 +22,7 @@ search_room_args = {
|
||||||
|
'division': fields.Str(),
|
||||||
|
'start_dt': fields.DateTime(),
|
||||||
|
'end_dt': fields.DateTime(),
|
||||||
|
- 'repeat_frequency': EnumField(RepeatFrequency),
|
||||||
|
+ 'repeat_frequency': fields.Enum(RepeatFrequency),
|
||||||
|
'repeat_interval': fields.Int(load_default=0),
|
||||||
|
'recurrence_weekdays': fields.List(fields.Str(validate=validate.OneOf(WEEKDAYS))),
|
||||||
|
'building': fields.Str(),
|
||||||
|
diff --git a/indico/modules/rb/schemas.py b/indico/modules/rb/schemas.py
|
||||||
|
index d9cafb8..1bc9854 100644
|
||||||
|
--- a/indico/modules/rb/schemas.py
|
||||||
|
+++ b/indico/modules/rb/schemas.py
|
||||||
|
@@ -11,7 +11,6 @@ from babel.dates import get_timezone
|
||||||
|
from flask import session
|
||||||
|
from marshmallow import ValidationError, fields, post_dump, post_load, validate, validates, validates_schema
|
||||||
|
from marshmallow.fields import Boolean, Date, DateTime, Function, Method, Nested, Number, Pluck, String
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from sqlalchemy import func
|
||||||
|
|
||||||
|
from indico.core.config import config
|
||||||
|
@@ -79,7 +78,7 @@ class AdminRoomSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
class RoomUpdateSchema(RoomSchema):
|
||||||
|
owner = Principal()
|
||||||
|
acl_entries = PrincipalPermissionList(RoomPrincipal)
|
||||||
|
- protection_mode = EnumField(ProtectionMode)
|
||||||
|
+ protection_mode = fields.Enum(ProtectionMode)
|
||||||
|
|
||||||
|
class Meta(RoomSchema.Meta):
|
||||||
|
fields = (*RoomSchema.Meta.fields, 'notification_before_days', 'notification_before_days_weekly', 'owner',
|
||||||
|
@@ -117,7 +116,7 @@ class RoomUpdateArgsSchema(mm.Schema):
|
||||||
|
max_advance_days = fields.Int(validate=lambda x: x >= 1, allow_none=True)
|
||||||
|
comments = fields.String()
|
||||||
|
acl_entries = PrincipalPermissionList(RoomPrincipal)
|
||||||
|
- protection_mode = EnumField(ProtectionMode)
|
||||||
|
+ protection_mode = fields.Enum(ProtectionMode)
|
||||||
|
|
||||||
|
|
||||||
|
class RoomEquipmentSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
@@ -185,11 +184,11 @@ class ReservationUserEventSchema(mm.Schema):
|
||||||
|
|
||||||
|
class ReservationOccurrenceLinkSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
id = Number()
|
||||||
|
- type = EnumField(LinkType, attribute='link_type')
|
||||||
|
+ type = fields.Enum(LinkType, attribute='link_type')
|
||||||
|
object = Nested(ReservationLinkedObjectDataSchema,
|
||||||
|
only=('url', 'title', 'event_title', 'event_url', 'start_dt', 'end_dt'))
|
||||||
|
start_dt = NaiveDateTime(attribute='reservation_occurrence.start_dt')
|
||||||
|
- state = EnumField(ReservationOccurrenceState, attribute='reservation_occurrence.state')
|
||||||
|
+ state = fields.Enum(ReservationOccurrenceState, attribute='reservation_occurrence.state')
|
||||||
|
|
||||||
|
@post_dump(pass_original=True)
|
||||||
|
def _hide_restricted_object(self, data, link, **kwargs):
|
||||||
|
@@ -204,7 +203,7 @@ class ReservationOccurrenceLinkSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
|
||||||
|
class ReservationOccurrenceSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
reservation = Nested(ReservationSchema)
|
||||||
|
- state = EnumField(ReservationOccurrenceState)
|
||||||
|
+ state = fields.Enum(ReservationOccurrenceState)
|
||||||
|
start_dt = NaiveDateTime()
|
||||||
|
end_dt = NaiveDateTime()
|
||||||
|
|
||||||
|
@@ -262,7 +261,7 @@ class ReservationDetailsSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
can_edit = Function(lambda booking: booking.can_edit(session.user))
|
||||||
|
can_reject = Function(lambda booking: booking.can_reject(session.user))
|
||||||
|
permissions = Method('_get_permissions')
|
||||||
|
- state = EnumField(ReservationState)
|
||||||
|
+ state = fields.Enum(ReservationState)
|
||||||
|
is_linked_to_objects = Function(lambda booking: bool(booking.links))
|
||||||
|
start_dt = NaiveDateTime()
|
||||||
|
end_dt = NaiveDateTime()
|
||||||
|
@@ -302,7 +301,7 @@ class ReservationDetailsSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
|
||||||
|
class BlockedRoomSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
room = Nested(RoomSchema, only=('id', 'name', 'sprite_position', 'full_name'))
|
||||||
|
- state = EnumField(BlockedRoomState)
|
||||||
|
+ state = fields.Enum(BlockedRoomState)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = BlockedRoom
|
||||||
|
@@ -398,7 +397,7 @@ class CreateBookingSchema(mm.Schema):
|
||||||
|
|
||||||
|
start_dt = fields.DateTime(required=True)
|
||||||
|
end_dt = fields.DateTime(required=True)
|
||||||
|
- repeat_frequency = EnumField(RepeatFrequency, required=True)
|
||||||
|
+ repeat_frequency = fields.Enum(RepeatFrequency, required=True)
|
||||||
|
repeat_interval = fields.Int(load_default=0, validate=lambda x: x >= 0)
|
||||||
|
recurrence_weekdays = fields.List(fields.Str(validate=validate.OneOf(WEEKDAYS)))
|
||||||
|
room_id = fields.Int(required=True)
|
||||||
|
@@ -406,7 +405,7 @@ class CreateBookingSchema(mm.Schema):
|
||||||
|
booking_reason = fields.String(data_key='reason', load_default='')
|
||||||
|
internal_note = fields.String()
|
||||||
|
is_prebooking = fields.Bool(load_default=False)
|
||||||
|
- link_type = EnumField(LinkType)
|
||||||
|
+ link_type = fields.Enum(LinkType)
|
||||||
|
link_id = fields.Int()
|
||||||
|
link_back = fields.Bool(load_default=False)
|
||||||
|
admin_override_enabled = fields.Bool(load_default=False)
|
||||||
|
@@ -561,7 +560,7 @@ class SettingsSchema(mm.Schema):
|
||||||
|
hide_module_if_unauthorized = fields.Bool()
|
||||||
|
tileserver_url = fields.String(validate=validate.URL(schemes={'http', 'https'}), allow_none=True)
|
||||||
|
booking_limit = fields.Int(validate=not_empty)
|
||||||
|
- booking_reason_required = EnumField(BookingReasonRequiredOptions, required=True)
|
||||||
|
+ booking_reason_required = fields.Enum(BookingReasonRequiredOptions, required=True)
|
||||||
|
notifications_enabled = fields.Bool()
|
||||||
|
notification_before_days = fields.Int(validate=validate.Range(min=1, max=30))
|
||||||
|
notification_before_days_weekly = fields.Int(validate=validate.Range(min=1, max=30))
|
||||||
|
diff --git a/indico/modules/search/controllers.py b/indico/modules/search/controllers.py
|
||||||
|
index a115a81..7f818d9 100644
|
||||||
|
--- a/indico/modules/search/controllers.py
|
||||||
|
+++ b/indico/modules/search/controllers.py
|
||||||
|
@@ -7,7 +7,6 @@
|
||||||
|
|
||||||
|
from flask import jsonify, session
|
||||||
|
from marshmallow import INCLUDE, fields
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
|
||||||
|
from indico.modules.categories.controllers.base import RHDisplayCategoryBase
|
||||||
|
from indico.modules.events.controllers.base import RHDisplayEventBase
|
||||||
|
@@ -46,7 +45,7 @@ class RHAPISearch(RH):
|
||||||
|
@use_kwargs({
|
||||||
|
'page': fields.Int(load_default=None),
|
||||||
|
'q': fields.String(required=True),
|
||||||
|
- 'type': fields.List(EnumField(SearchTarget), required=True),
|
||||||
|
+ 'type': fields.List(fields.Enum(SearchTarget), required=True),
|
||||||
|
'admin_override_enabled': fields.Bool(
|
||||||
|
load_default=False,
|
||||||
|
validate=validate_with_message(lambda value: session.user and session.user.is_admin,
|
||||||
|
diff --git a/indico/modules/search/result_schemas.py b/indico/modules/search/result_schemas.py
|
||||||
|
index 88c274e..96efa43 100644
|
||||||
|
--- a/indico/modules/search/result_schemas.py
|
||||||
|
+++ b/indico/modules/search/result_schemas.py
|
||||||
|
@@ -6,7 +6,6 @@
|
||||||
|
# LICENSE file for more details.
|
||||||
|
|
||||||
|
from marshmallow import EXCLUDE, ValidationError, fields
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from marshmallow_oneofschema import OneOfSchema
|
||||||
|
|
||||||
|
from indico.core.db.sqlalchemy.links import LinkType
|
||||||
|
@@ -63,7 +62,7 @@ def require_search_target(target):
|
||||||
|
|
||||||
|
|
||||||
|
class CategoryResultSchema(ResultSchemaBase):
|
||||||
|
- type = EnumField(SearchTarget, validate=require_search_target(SearchTarget.category))
|
||||||
|
+ type = fields.Enum(SearchTarget, validate=require_search_target(SearchTarget.category))
|
||||||
|
category_id = fields.Int(required=True)
|
||||||
|
title = fields.String(required=True)
|
||||||
|
url = fields.Method('_get_url')
|
||||||
|
@@ -83,7 +82,7 @@ class LocationResultSchema(mm.Schema):
|
||||||
|
|
||||||
|
class EventResultSchema(ResultSchemaBase):
|
||||||
|
#: The record type
|
||||||
|
- type: SearchTarget = EnumField(SearchTarget, validate=require_search_target(SearchTarget.event))
|
||||||
|
+ type: SearchTarget = fields.Enum(SearchTarget, validate=require_search_target(SearchTarget.event))
|
||||||
|
#: The event id
|
||||||
|
event_id = fields.Int(required=True)
|
||||||
|
#: The event title
|
||||||
|
@@ -91,7 +90,7 @@ class EventResultSchema(ResultSchemaBase):
|
||||||
|
#: The event description
|
||||||
|
description = fields.String(required=True)
|
||||||
|
#: The event type
|
||||||
|
- event_type = EnumField(EventType, required=True)
|
||||||
|
+ event_type = fields.Enum(EventType, required=True)
|
||||||
|
#: The event start date time
|
||||||
|
start_dt = fields.DateTime(required=True)
|
||||||
|
#: The event end date time
|
||||||
|
@@ -111,7 +110,7 @@ class EventResultSchema(ResultSchemaBase):
|
||||||
|
|
||||||
|
class ContributionResultSchema(ResultSchemaBase):
|
||||||
|
#: The record type
|
||||||
|
- type: SearchTarget = EnumField(SearchTarget, validate=require_search_target(SearchTarget.contribution))
|
||||||
|
+ type: SearchTarget = fields.Enum(SearchTarget, validate=require_search_target(SearchTarget.contribution))
|
||||||
|
#: The contribution id
|
||||||
|
contribution_id = fields.Int(required=True)
|
||||||
|
#: The contribution event id
|
||||||
|
@@ -150,7 +149,7 @@ class ContributionResultSchema(ResultSchemaBase):
|
||||||
|
|
||||||
|
class SubContributionResultSchema(ContributionResultSchema):
|
||||||
|
#: The record type
|
||||||
|
- type: SearchTarget = EnumField(SearchTarget, validate=require_search_target(SearchTarget.subcontribution))
|
||||||
|
+ type: SearchTarget = fields.Enum(SearchTarget, validate=require_search_target(SearchTarget.subcontribution))
|
||||||
|
#: The sub-contribution id
|
||||||
|
subcontribution_id = fields.Int(required=True)
|
||||||
|
|
||||||
|
@@ -188,7 +187,7 @@ def _get_event_path(obj):
|
||||||
|
|
||||||
|
class AttachmentResultSchema(ResultSchemaBase):
|
||||||
|
#: The record type
|
||||||
|
- type: SearchTarget = EnumField(SearchTarget, validate=require_search_target(SearchTarget.attachment))
|
||||||
|
+ type: SearchTarget = fields.Enum(SearchTarget, validate=require_search_target(SearchTarget.attachment))
|
||||||
|
#: The attachment id
|
||||||
|
attachment_id = fields.Int(required=True)
|
||||||
|
#: The attachment folder id
|
||||||
|
@@ -206,7 +205,7 @@ class AttachmentResultSchema(ResultSchemaBase):
|
||||||
|
#: The attachment author
|
||||||
|
user: PersonSchema = fields.Nested(PersonSchema, load_default=None)
|
||||||
|
#: The attachment type
|
||||||
|
- attachment_type: AttachmentType = EnumField(AttachmentType, required=True)
|
||||||
|
+ attachment_type: AttachmentType = fields.Enum(AttachmentType, required=True)
|
||||||
|
#: The attachment last modified date time
|
||||||
|
modified_dt = fields.DateTime(required=True)
|
||||||
|
# extra fields that are not taken from the data returned by the search engine
|
||||||
|
@@ -227,7 +226,7 @@ class AttachmentResultSchema(ResultSchemaBase):
|
||||||
|
|
||||||
|
class EventNoteResultSchema(ResultSchemaBase):
|
||||||
|
#: The record type
|
||||||
|
- type: SearchTarget = EnumField(SearchTarget, validate=require_search_target(SearchTarget.event_note))
|
||||||
|
+ type: SearchTarget = fields.Enum(SearchTarget, validate=require_search_target(SearchTarget.event_note))
|
||||||
|
#: The note id
|
||||||
|
note_id = fields.Int(required=True)
|
||||||
|
#: The note event id
|
||||||
|
diff --git a/indico/modules/users/controllers.py b/indico/modules/users/controllers.py
|
||||||
|
index 5cb5047..52c7a51 100644
|
||||||
|
--- a/indico/modules/users/controllers.py
|
||||||
|
+++ b/indico/modules/users/controllers.py
|
||||||
|
@@ -15,7 +15,6 @@ from flask import flash, jsonify, redirect, render_template, request, session
|
||||||
|
from itsdangerous import BadSignature
|
||||||
|
from markupsafe import Markup, escape
|
||||||
|
from marshmallow import fields
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from PIL import Image
|
||||||
|
from sqlalchemy.orm import joinedload, load_only, subqueryload
|
||||||
|
from sqlalchemy.orm.exc import StaleDataError
|
||||||
|
@@ -337,7 +336,7 @@ class RHProfilePicturePreview(RHUserBase):
|
||||||
|
|
||||||
|
flash_user_status = False
|
||||||
|
|
||||||
|
- @use_kwargs({'source': EnumField(ProfilePictureSource)}, location='view_args')
|
||||||
|
+ @use_kwargs({'source': fields.Enum(ProfilePictureSource)}, location='view_args')
|
||||||
|
def _process(self, source):
|
||||||
|
if source == ProfilePictureSource.standard:
|
||||||
|
first_name = self.user.first_name[0].upper() if self.user.first_name else ''
|
||||||
|
@@ -374,7 +373,7 @@ class RHSaveProfilePicture(RHUserBase):
|
||||||
|
"""Update the user's profile picture."""
|
||||||
|
|
||||||
|
@use_kwargs({
|
||||||
|
- 'source': EnumField(ProfilePictureSource, required=True)
|
||||||
|
+ 'source': fields.Enum(ProfilePictureSource, required=True)
|
||||||
|
})
|
||||||
|
def _process(self, source):
|
||||||
|
self.user.picture_source = source
|
||||||
|
@@ -885,7 +884,7 @@ class RHRejectRegistrationRequest(RHRegistrationRequestBase):
|
||||||
|
class UserSearchResultSchema(mm.SQLAlchemyAutoSchema):
|
||||||
|
affiliation_id = fields.Integer(attribute='_affiliation.affiliation_id')
|
||||||
|
affiliation_meta = fields.Nested(AffiliationSchema, attribute='_affiliation.affiliation_link')
|
||||||
|
- title = EnumField(UserTitle, attribute='_title')
|
||||||
|
+ title = fields.Enum(UserTitle, attribute='_title')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = User
|
||||||
|
diff --git a/indico/util/marshmallow.py b/indico/util/marshmallow.py
|
||||||
|
index fed7293..b331b4a 100644
|
||||||
|
--- a/indico/util/marshmallow.py
|
||||||
|
+++ b/indico/util/marshmallow.py
|
||||||
|
@@ -14,7 +14,6 @@ import yaml
|
||||||
|
from dateutil import parser, relativedelta
|
||||||
|
from marshmallow import Schema, ValidationError, fields
|
||||||
|
from marshmallow.utils import from_iso_datetime
|
||||||
|
-from marshmallow_enum import EnumField
|
||||||
|
from pytz import timezone
|
||||||
|
from speaklater import _LazyString
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
@@ -500,7 +499,7 @@ class LowercaseString(fields.String):
|
||||||
|
return super()._deserialize(value, attr, data, **kwargs).lower()
|
||||||
|
|
||||||
|
|
||||||
|
-class NoneValueEnumField(EnumField):
|
||||||
|
+class NoneValueEnumField(fields.Enum):
|
||||||
|
"""
|
||||||
|
Like the normal EnumField, but when receiving a None value,
|
||||||
|
this is mapped to a specific enum member.
|
||||||
|
diff --git a/requirements.in b/requirements.in
|
||||||
|
index 54be3ee..fd12cfa 100644
|
||||||
|
--- a/requirements.in
|
||||||
|
+++ b/requirements.in
|
||||||
|
@@ -36,7 +36,6 @@ lxml[html5]
|
||||||
|
markdown
|
||||||
|
markupsafe
|
||||||
|
marshmallow-dataclass
|
||||||
|
-marshmallow-enum
|
||||||
|
marshmallow-oneofschema
|
||||||
|
marshmallow-sqlalchemy
|
||||||
|
marshmallow
|
||||||
|
diff --git a/requirements.txt b/requirements.txt
|
||||||
|
index e1112a7814..53c2d521de 100644
|
||||||
|
--- a/requirements.txt
|
||||||
|
+++ b/requirements.txt
|
||||||
|
@@ -211,14 +211,11 @@ marshmallow==3.22.0
|
||||||
|
# -r requirements.in
|
||||||
|
# flask-marshmallow
|
||||||
|
# marshmallow-dataclass
|
||||||
|
- # marshmallow-enum
|
||||||
|
# marshmallow-oneofschema
|
||||||
|
# marshmallow-sqlalchemy
|
||||||
|
# webargs
|
||||||
|
marshmallow-dataclass==8.7.0
|
||||||
|
# via -r requirements.in
|
||||||
|
-marshmallow-enum==1.5.1
|
||||||
|
- # via -r requirements.in
|
||||||
|
marshmallow-oneofschema==3.1.1
|
||||||
|
# via -r requirements.in
|
||||||
|
marshmallow-sqlalchemy==1.1.0
|
34
pkgs/pynpm/default.nix
Normal file
34
pkgs/pynpm/default.nix
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
wheel,
|
||||||
|
babel,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "pynpm";
|
||||||
|
version = "0.2.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "inveniosoftware";
|
||||||
|
repo = "pynpm";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-GjfylyxPZrRGCLuNZejmTdQGz5JugKHYpVix8WF/8QK=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [
|
||||||
|
setuptools
|
||||||
|
wheel
|
||||||
|
babel
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Python interface to your NPM and package.json";
|
||||||
|
homepage = "https://github.com/inveniosoftware/pynpm";
|
||||||
|
changelog = "https://github.com/inveniosoftware/pynpm/blob/${version}/CHANGES.rst";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
41
pkgs/pywebpack/default.nix
Normal file
41
pkgs/pywebpack/default.nix
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
wheel,
|
||||||
|
babel,
|
||||||
|
importlib-metadata,
|
||||||
|
pynpm,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "pywebpack";
|
||||||
|
version = "2.1.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "inveniosoftware";
|
||||||
|
repo = "pywebpack";
|
||||||
|
rev = "refs/tags/v${version}";
|
||||||
|
hash = "sha256-6hK/k+26Iqb6BE/pv2iFFg5OH6247AAGpvOV6dDRKRT=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [
|
||||||
|
setuptools
|
||||||
|
wheel
|
||||||
|
babel
|
||||||
|
];
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
importlib-metadata
|
||||||
|
pynpm
|
||||||
|
];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Webpack integration layer for Python";
|
||||||
|
homepage = "https://github.com/inveniosoftware/pywebpack";
|
||||||
|
changelog = "https://github.com/inveniosoftware/pywebpack/blob/${version}/CHANGES.rst";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
36
pkgs/wtforms-dateutil/default.nix
Normal file
36
pkgs/wtforms-dateutil/default.nix
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
wtforms,
|
||||||
|
python-dateutil,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "wtforms-dateutil";
|
||||||
|
version = "0.1.0";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "wtforms";
|
||||||
|
repo = "wtforms-dateutil";
|
||||||
|
rev = "refs/tags/${version}";
|
||||||
|
hash = "sha256-k1DZqf2FgyupNvRIIrPLwxbTP5MteCnvASCkpCZRyAE=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [ setuptools ];
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
wtforms
|
||||||
|
python-dateutil
|
||||||
|
];
|
||||||
|
|
||||||
|
pythonImportChecks = [ "wtforms_dateutil" ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "WTForms fields using dateutil";
|
||||||
|
homepage = "https://github.com/pallets-eco/wtforms-dateutil";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
37
pkgs/wtforms-sqlalchemy/default.nix
Normal file
37
pkgs/wtforms-sqlalchemy/default.nix
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
fetchFromGitHub,
|
||||||
|
buildPythonPackage,
|
||||||
|
setuptools,
|
||||||
|
sqlalchemy,
|
||||||
|
wtforms,
|
||||||
|
}:
|
||||||
|
|
||||||
|
buildPythonPackage rec {
|
||||||
|
pname = "wtforms-sqlalchemy";
|
||||||
|
version = "0.4.1";
|
||||||
|
pyproject = true;
|
||||||
|
|
||||||
|
src = fetchFromGitHub {
|
||||||
|
owner = "wtforms";
|
||||||
|
repo = "wtforms-sqlalchemy";
|
||||||
|
rev = "refs/tags/${version}";
|
||||||
|
hash = "sha256-uR09LYfcyre+AC2TTEIhpjSI7y4Yo0GJ20smkzo5PRY=";
|
||||||
|
};
|
||||||
|
|
||||||
|
build-system = [ setuptools ];
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
sqlalchemy
|
||||||
|
wtforms
|
||||||
|
];
|
||||||
|
|
||||||
|
pythonImportsCheck = [ "wtforms_sqlalchemy" ];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "WTForms integration for SQLAlchemy";
|
||||||
|
homepage = "https://github.com/wtforms/wtforms-sqlalchemy";
|
||||||
|
changelog = "https://github.com/wtforms/wtforms-sqlalchemy/blob/${version}/CHANGES.rst";
|
||||||
|
license = lib.licenses.bsd3;
|
||||||
|
};
|
||||||
|
}
|
116
profiles/indico.nix
Normal file
116
profiles/indico.nix
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
{ config, lib, pkgs, python3, ... }:
|
||||||
|
let
|
||||||
|
# cfg = config.services.indico;
|
||||||
|
# pythonFmt = pkgs.formats.pythonVars { };
|
||||||
|
indico = pkgs.callPackage ../pkgs/indico { };
|
||||||
|
pythonEnv = indico.python.withPackages (ps: [
|
||||||
|
indico
|
||||||
|
# (ps.toPythonModule indico)
|
||||||
|
ps.gunicorn
|
||||||
|
]);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
# TODO cProfile; indico is *very* slow (~30s just to print the help)
|
||||||
|
|
||||||
|
# + sudo indico
|
||||||
|
environment.systemPackages = [ indico ];
|
||||||
|
|
||||||
|
services.redis.servers.indico.enable = true;
|
||||||
|
|
||||||
|
systemd.services.indico-web = {
|
||||||
|
description = "Indico web service";
|
||||||
|
after = [
|
||||||
|
"network.target"
|
||||||
|
"redis-indico.service"
|
||||||
|
"postgresql.service"
|
||||||
|
];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
# TODO migrations
|
||||||
|
serviceConfig = {
|
||||||
|
User = "indico";
|
||||||
|
Group = "indico";
|
||||||
|
ExecStart = "${lib.getExe' pythonEnv "gunicorn"} --bind unix:/run/indico/indico.sock --name=indico indico.wsgi";
|
||||||
|
Restart = "on-failure";
|
||||||
|
};
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.sockets.gunicorn-web = {
|
||||||
|
socketConfig = {
|
||||||
|
ListenStream = "/run/indico/indico.sock";
|
||||||
|
SocketUser = "nginx";
|
||||||
|
};
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
# preStart = ''
|
||||||
|
# echo "create extension if not exists pg_trgm" | runuser -u ${config.services.postgresql.superUser} -- ${config.services.postgresql.package}/bin/psql hydra
|
||||||
|
# ''
|
||||||
|
|
||||||
|
services.postgresql = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.postgresql_16;
|
||||||
|
ensureDatabases = [ "indico" ];
|
||||||
|
ensureUsers = [
|
||||||
|
{
|
||||||
|
name = "indico";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||||
|
|
||||||
|
services.nginx = let
|
||||||
|
indicoBaseDir = "/tmp";
|
||||||
|
in {
|
||||||
|
enable = true;
|
||||||
|
recommendedTlsSettings = true;
|
||||||
|
recommendedOptimisation = true;
|
||||||
|
recommendedGzipSettings = true;
|
||||||
|
recommendedProxySettings = true;
|
||||||
|
upstreams.indico.servers."unix:/run/indico/indico.sock" = { };
|
||||||
|
virtualHosts."events.federez.net" = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations = {
|
||||||
|
"/.xsf/indico/" = {
|
||||||
|
alias = "${indicoBaseDir}/";
|
||||||
|
extraConfig = ''
|
||||||
|
internal;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
# Order? + too lax?
|
||||||
|
"~ ^/(images|fonts)(.*)/(.+?)(__v[0-9a-f]+)?\\.([^.]+)$" = {
|
||||||
|
alias = "${indicoBaseDir}/web/static/$1$2/$3.$5";
|
||||||
|
extraConfig = ''
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"~ ^/(css|dist|images|fonts)/(.*)$" = {
|
||||||
|
alias = "${indicoBaseDir}/web/static/$1/$2";
|
||||||
|
extraConfig = ''
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
"= /robots.txt" = {
|
||||||
|
alias = "${indicoBaseDir}/web/static/robots.txt";
|
||||||
|
extraConfig = ''
|
||||||
|
access_log off;
|
||||||
|
'';
|
||||||
|
"/" = {
|
||||||
|
proxyPass = "http://indico";
|
||||||
|
extraConfig = ''
|
||||||
|
client_max_body_size 1G;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
users.users.indico = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "indico";
|
||||||
|
};
|
||||||
|
|
||||||
|
users.groups.indico = {};
|
||||||
|
}
|
|
@ -1,33 +1,33 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 oDAQrw NFtzIriHmvcPmluvbL9yV5fAFKoBWcuY4M3Qy1PogkU
|
-> ssh-ed25519 oDAQrw SBbVb1mkK/vYXtTNGbb7l0sNuusSObbrp6ft41xUHCo
|
||||||
KxRzRwZhrvVxvvRkuVsumYRbUDXsYecvmvKR8osv4/s
|
7BokqAWzTauGghPtytuJ/GN1qD+1kZAHGbiKrb4yc2U
|
||||||
-> ssh-rsa krWCLQ
|
-> ssh-rsa krWCLQ
|
||||||
e6/eduQLNkjdwInZNonT6xtrRAtlt8UJqrTvUajsfQzR+AcFfcMGuOdzwRIAdbMq
|
isST86UT1UMMOKiaTWaREFMn22H1MPDbLbuIeZzBhkTh0GnzmKKCxZV7+wPX4Woc
|
||||||
lC8mICFn+9RwwA1360CFSGSZOBrhWnY5Ov9KPsXGOYiup4/fDwk6NJxurnTSJVrb
|
mq9FtkQBcbawrV20ZafF4bKqBl2ByuDmqe+VVWLchrR0DdkspsEBBHIw42rG79ZU
|
||||||
EUyBQoeds9ZnHlQ9Jq5tjnzVo0gIIm1ixtOq9XnAos4tiDzviZgjimJRZL7zW7Zd
|
x+nNXnsDAFMdLRBEcNZSBVoGd1KhTuyoOM91dJ1IueJx3j8SA5JNCIG1Zf8vJKqX
|
||||||
4FQBwXSn8rTT7/gBM4oDbDmBcrbAf9YcP9Wspsye1XgTG/KyqRT75VAJu2l7fUnU
|
WuZtjQiI949wzfU0WX+T5hT0uMzuzeIJ993vUJ2+2twN+KQnq0JYMTG26g40tSH+
|
||||||
DIlqmQbPPkSIO4MURPXpAg8S3tXAC6fs69s77dq9+NfbvK0TH7blaJYcJiW7ogYY
|
uAENRS6dwQep5BI5nnx1yKli3zX2Dc+4MLXiglKCxkyZ4sjYtfzMnlaAfpahyxVm
|
||||||
RTwOG61y78IV55Ze9/9M6A
|
8i37qYGdyyxLPRWxS3SMUQ
|
||||||
-> ssh-ed25519 /vwQcQ DKJKkbb0RO1jfSBH3KR0OGMfj0ZJQYVz7GDUMP/bJwE
|
-> ssh-ed25519 /vwQcQ Ig4WFFJ4Ex6cYghg14FJJfskUKyI5gWJwd5vn0XmDH8
|
||||||
vzNWlrkN3UYst11R3opQSdz/pnd48gWmsv3jv/g+3+A
|
uHwxOnD8aVeG8YwiMhcj2BB6q3o+CfM6C7GP3jcXjyo
|
||||||
-> ssh-ed25519 0R97PA i+He+K6aBSItKmvA/2rvtS4IfqBK2rOYOBhTURMPqQ4
|
-> ssh-ed25519 0R97PA UvK0BtCJBVNnc2rcpz49iwdqmIt31aAXVFvTZw6/Fyk
|
||||||
k+FuDsFbS1MNT5vEzYSny80FBU+L+OdxMGEAT3e/VP0
|
fcZquflamVQnWRQVL+NsUwiQaJs9Qzi+Va5wrg0pa1k
|
||||||
-> ssh-rsa jL+Elw
|
-> ssh-rsa jL+Elw
|
||||||
pex+P4zsbQhndeUZC/DsmRIYLaclvAMR75NxwQIhlzXTvARWfrClhTXmD0cmA2QM
|
PkFLMHXHnXNGVKK2RkR59ewNPMJOc5IE6AFums1vTELWlhvNZdD0Icz5yicVf/Fs
|
||||||
hMvtDADwW/RRkFZuVKY/u6dA4/yZdua8by1RITrnLVAYDqr7H2u7bCozESJChJJw
|
cNoj6L2H/U33liAj9oUYr7bDv+4l41hHQskpSz6l2PoyAfWXJzFCF8fGHSucjRD7
|
||||||
XsNglDQ2Zkw9le4EjX0oO7hyt5eM07DYnq3nmFuqVUzWh1qvxOtcELkOE/fi0AwJ
|
c4v7ZJ/vt7V+IUjz9aAxO6iWwairBMMY+DUifu8a0N2UWyBKt0ry5pKXX20DSWjf
|
||||||
RvrGbM27w0V6N7BYAefBbVc+OFbNg2ai0WECxlL4HXR9BgmVYGybYR+11Bu4scCM
|
rI7M1bBxLUZRK2gljV7lm5BwTzAsLey7R6dlIzcI3cRg8GZ1TKyzaIOil3lfP1nM
|
||||||
mS9CKbW4UtVhK+tPVEgO3gymwv99PYFwcwvdGdyAAp9yVgjbKZt9Lm6J/eNpj/82
|
OhJb4SCTiJ+xYRagTQfgtudvSDfnCV0EvGx6h1vG2OxTq6rfUYtou3Lan2UMeTBJ
|
||||||
YMYW6ZBK0jdtT4YSNu/88EXoQghoOyCEbFAYXoHiaNCiFxcKOOdY65B1SATi1Cuh
|
UKjptcnlWIKyjYSxwRjRmd/eypJKu6KY82j1ejrbzU8I11Yckpi1ea0huRyFQ2I7
|
||||||
Qqo3Ejfx7waS3iArPFQFzS4X5ZKtj3GaHXKQkziD7GmP9cjGWt7S8Wh9pi/G6Bx1
|
dNsyG/Zq8qaWSXVmMX+Cpn9U15UOoI92bGqN0SVHI+rKodxVIgeALflbZZWcEsta
|
||||||
vGFhdfwtd+pGlbhrXd5jU6+UnVGtPBmgN8F/CpvqII4HN62Ds+npUs31uFGW1lzl
|
CktzPwndyCdAhv9+N3QFMinUM4QFeoLdsmMES6k8+ZqIsPqg/rFWXPyacCuHSk6e
|
||||||
b4q+ij3s/Obt7HHCAhywXfnTDZ15WDcU8cWfSlsoTd63sc8INYXvDzFX46kax0E+
|
x6rLddq+htSusCxVtzQu9ugXNlDDKUMprJ/XDKQ2FefqVB0O2m4mqmzKCWgMnB/A
|
||||||
yqGoFzYuke0FJxUf/tll4wv5aY9RcgAoHsDP7CL8nB1556NwVYFn8AujY87IiNAw
|
yQgR77twWH9nfv0RyhkqjkqU9AS1tIsXGttuFAODlkQpLtkWarDj7x8juQnHd4pS
|
||||||
G/WSn9URjTgxW1YhiIvJ5L3mp/DjAZiakCU/85KEf08
|
FcKR1siEFmBV0BbjgPU7CC+HWovKl5f/GLYgPfstHM4
|
||||||
-> ssh-ed25519 jIXfPA pPEvleLgX5FDDHbWlq6Szu61VMt4W7e3HrM5bYQA4QU
|
-> ssh-ed25519 jIXfPA HCM4xJkLVRfAvBzKyS5OZsbu91HPeZgx8sbwUP58LiY
|
||||||
Ag8v967xi0AEbg8fiYAAmA36rkdZETCb3q/veoRdEbA
|
GqJebsL5u0W66xU+cmXHbn7pYo7m//LggPIc3pWdJOQ
|
||||||
-> ssh-ed25519 um7xWA gkxkaZftmupdeK1fsi7v59wAsM/Usc8SXjmxRkoBjmM
|
-> ssh-ed25519 um7xWA CCztuWK8B5skJS0xkpyo1cIci512Pmsi4Xp3M6Kf9DA
|
||||||
cjiizU43+Fed3vFqOpoePhicklpsSoAhEHZhHlkXr5Q
|
NUEcXszN91ycADY9oGKTGFWnCzv8ZIfEQ3zdkqm6/sg
|
||||||
--- Xw/OABODZr4PGKpuNi03kdUptlyHF8hEK3+KtDulu7U
|
--- eW8lDje70BhCexL17jXBtSA2X/jCnVwZUvackCd1bd0
|
||||||
ŽÿÕ¶<18>éqkÐ<ªŸAã4z<34>ξ†>ð:hÉÞàM<>îÌq&ï †eZI
|
ÕËüë<C¤Àáï°ó¥o¦åÖ$ŠŽ¿¿
Qdžâ}˜HÏb©Þ-ýA;Oð«)þ*>·Þ›™¼y˜|ŠˆL¤
|
||||||
ŸÐàq•ÁI·[3Ëv|þDhúQékb¿S|Síx"Õ´Œ½¾´P숸<CB86>špEhư¨ÉXû<58>U<oÿ'ó{©1wÇ$:€÷aò!<9_Ê/<2F>ýæÍ«ÝBüÑÙæDm¯Ç"¨3Hk¡<6B>´…Ä
|
ûâGQÙÌŽAŸïà¢-2ω}xùŽ–˜×ƒh*ÿqåôÃLp›@Å~Ek¾Ûô._åês–&·—cŠ)<29> ²Óòm~;†ƒEÏð|ët|×oùíšÞZÖ¦"<22>Ì
|
|
@ -1,32 +1,33 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 oDAQrw +aORlGGz/jqX0t4opGM5vMTgBKtAdL/z1KxfA4C43To
|
-> ssh-ed25519 oDAQrw QeSmwUu/CvV+1LIgeeGEW6PFgOESwqTe1o7Ack1PWSs
|
||||||
MNbp/PaSnpvyfZtmWWD6HYG3yHh2uWoXDY8V1Ft7+ac
|
Z4a8OsJAYdnJfG5IZq/ktMD9F3pfN3cjim8A2nZM5a4
|
||||||
-> ssh-rsa krWCLQ
|
-> ssh-rsa krWCLQ
|
||||||
2Px6I6WuRr10mMWlcUCAbnm6dyQa2hklmnwXtNPWXmKNPzHC6CGoye5dnOvkNKGN
|
GnsaM6qYR58TY9xfDvFOD9On6jHuU6M5ku5hQExsdGFXkp+pultLC4d31iO/9YAw
|
||||||
5ekf2mK2ywzE2FQFVYOtY3Ss/60I4OTXmxNJ3qrCAU2z+f+53nAegguc3tB4Xvh8
|
NC+DjYRfQRgiVl7Ik7l5EbsoJitBsyJqNm6KckLgMr+m36i2l7myrUCXvkj29WPY
|
||||||
tQVQICaX1oVU/PD2SFX8QcTBORF2+Vc0Nd6fbuGl3dhSeESg7JLj5oaBCsthZD2J
|
s2uRmlo4Ai6pthu2nI7dJJ0Va/Z3WtXOb+q2QIapbB/Jb3mcvkVbKkJNnVWpZjri
|
||||||
U1ehTDS/+t6nogt1BdNZK10yFXRGk44jDMADMvvUPkIEW7mbvTFfMtXNhbemOn+X
|
pafvy1ZlbWtOIHUHfLCyBo3R2sDQUFR8LL5Ww93CzjbiyfBVe0lgBvJJJUoZ+7qj
|
||||||
oIXt8DNwzn3tF1IdOJ+vjtcU3gqYQYZVFKJV1DtQSA7i46Dl0J0+12+8/zKMX+yu
|
ZPykqASPNsKW+IQXb90BZlpf9JRi9l8VawZ1OCasWZ8e7UBvxMp/mpcZ9mUWDE+g
|
||||||
NKcaa/L1tz0lPX6ZeXhoOg
|
uvcAaBjx0ZHsN1u+k3Sx1A
|
||||||
-> ssh-ed25519 /vwQcQ QoEbQ1IA4EKR97Fqa/NQN9RDUEubeZbvxMcd0ZFhwyU
|
-> ssh-ed25519 /vwQcQ jCxoSbDPpFe7eHJEX3rov05XWPkWDZvIRbiWhvJmsAI
|
||||||
OAFrGGXCxDFcsalinhG3JcXUj+RJawl6UnSgZkBwBrk
|
+ivctO51LaGMF9PJHGhwLRNXXxq8VZSfnbjHIU6lE4M
|
||||||
-> ssh-ed25519 0R97PA VkKhx5oVdrFjjSXwreIiGnH0nZEqY5Ls4OSpgpDn0jI
|
-> ssh-ed25519 0R97PA 0GSdrtGAYks1eSMQXispNZTaa+UIQbP0eAzRP/aoXS4
|
||||||
FC9SN+Woh6QBWV5r5TjtjFSp8mqw3LxgFJCQPjD8oss
|
MNmpUVS/D5AxNaKfvxlqd5WW2+0cHjDo7/74vCzPDMU
|
||||||
-> ssh-rsa jL+Elw
|
-> ssh-rsa jL+Elw
|
||||||
UGQRNdtkdNbRVcoimpZsgBAGp95mtHwJ8V4CwlL82GqdIGM3LQDrCtPgFTC1C4Zx
|
LWL7LZ+16Bnk2o/5/2QJq9UHqdUBXndU/lx+UqGSemcEJqbuikWEq5Sv9jTgME2U
|
||||||
lrgVaT/xi4WhRkkHCd0ZTzJ5i9NY9H/gnDaXKeKcTcQezH1yeMBLns92D2z7u0+1
|
mQYMr10vGxyDo0mSB9pbYGB5fWlAi61UutQKJuuwHgETF56fVy7+fsRmtokIcG7C
|
||||||
DyTzu8ZzZLvaej2b7gLU6u2BMC10AnBYP0LFuZlE3ndnr7ro9flKPb5A+IRbX339
|
dF2ooUsx5/Ul2V0o2v4KieOZhU4KvhPwHVUdP6SkWCtn5kxrmJkbOjOrRNOVZffz
|
||||||
xkNlIOsTBdSfJJ27LKZVIOUS2Pxg1Kos9Wtbg1QsgeikdrA++QD0GhrRd+X4sFrf
|
yOuViZlLlFrtzqtuwBi6uHhoz5x0t+m/v1JM1/zHFI5I3JPEpHvRfVKp7K2dOT2T
|
||||||
Xfjq12XDakCfLmvi9QLJ2hy4X1glCO1lsBocDEaa2dGQMa2yVQi72z/92w83g98C
|
nr7UotsoGD2+nqrSp4YVgNdwy6EgjbVKGKF2rDr1hcUyMV+L8vRmAxQhfAWJxPYh
|
||||||
UO25VkpKwdGFBf8PfhKeEkdSQEJUNOe3mlTEvtpr5S3BM+//fSFHlaS1UMEeamC2
|
jOgHWIWOCLQX/6MrBB4+gvyNvrZUw6nvDwbMiMlVn6MS6H395Sh42PtiCnx27pc4
|
||||||
OrcvTwdby9f4l0++9dEuPcgQYvMzbUndwFn2HI7a8fGSIF6iXeVdrl5zuR3Wgugr
|
xIGB4Zaq+38SnkpjqLVwSUak7rC0FHHu6nTUIQPIktmz8C1BWpNpTL4mtuT30U45
|
||||||
ksMiQ6IyItrv/XlR5945dTxragWIwDeNJFE5EEYU3F7ryhT1FMKUWlt3lDazVuuj
|
MVKB1taKk87XVpqzxOgQVHa3CZzjANm8cpip4yWkcEskhv+3OZjeZNgkUHHR1KGE
|
||||||
PoLjUnXNhi7I+3XZ22e5P2BW7UmMbsPg3M9l+u+1U1vk/o28cZxrWV6VW4MB1Aiv
|
suZxJJTrhhabV1N69i5LqmXgr4BZcJEkkdoJ4bFUaPttwkm6aUDpdSJbRowyzDbX
|
||||||
TXFXZSl123ag32PdKZ/dV7p4VC4hXEqyLA7qIrE9rFduEI5WQHqd1iL/pGxEOnuM
|
DWzmG/P1IpTdRw/7lKR7WUDMjsUmdMwCWpwlNetHM9t9aS62GBT2JKtTWfAPwdWw
|
||||||
AOe/acgmB1hhVLCAwCCpERWyC1+Bn7UWRjrPKCLfqFc
|
VeGpq5o2R2EBW7ioVO3P14Mk3duD/PB8H8xr+gEczbA
|
||||||
-> ssh-ed25519 jIXfPA NaF9Sg7UkShfSzE59iFwKF4WMsc0xtAejl+20EQBNzc
|
-> ssh-ed25519 jIXfPA UhMaLIx8smNo4NoGkyh7ODvqOqhql4bI+vZsz8WKugE
|
||||||
4CJqeGTxwcG0ObXeWATVKQkqlyaKZEaHFfGBOc6Xpok
|
d1PVZiDWykjx86YDlChW1BrLU/NHbHRfnnJ+m/eCIGQ
|
||||||
-> ssh-ed25519 um7xWA rlZ0xF57VNq1KHijaV9csD+Sq6cfp5DM9k1uuVOhLyY
|
-> ssh-ed25519 um7xWA rjgDG4Rpaq0R54at3sc8TSUM1ipBAUq5Zl/di7i7jFc
|
||||||
7uYk1RIET7bkdXTHJdocqOiEtc6vqY4iOBB4cMJ7CyQ
|
G8XdosKSH6xxMMWFD5DbtyDdgNvfegbw1zEmTMI/TfU
|
||||||
--- FiH1HnZbKHvI9kclq8TrOFlQN6hvNd9M0mxdqjYM5gw
|
--- Unyyf+PuoDOyqfNttxSNFPJrbmkLATNL03J0DbR9AxU
|
||||||
õõkjŠüª—p[ÉtäÏ–UÎ9Þdc–Ú—<C39A>N«•E#™²c|’Òۃ䋷`¡û§GWMy€v$àdü–±
|
”ÙÚé~¯bɸ@éô¢Ó;ÙŸ|Õþ+;úC-aо!3¡L>kà
|
||||||
|
3ý<EFBFBD>·4Èløq¦Á‰Mvî–]<5D>Pýú‚-Y¥9
|
Binary file not shown.
|
@ -1,34 +1,33 @@
|
||||||
age-encryption.org/v1
|
age-encryption.org/v1
|
||||||
-> ssh-ed25519 GxF6ZA pCpuN1PDIOfZ4ZewmIv4YWNAbWy3FHQsvMumPHpGOjw
|
-> ssh-ed25519 GxF6ZA y3IlZBxYfMnMpuWDjVDdT1zE6+bDWyl2pbxuUvwXbEI
|
||||||
nGgBgGw+65u7+tASWpfk30cc2TzgVJGFdDz6Ar/R+5s
|
N4VsbsnYD2b0TqSE1P2DzuaKT6gnYOjCA/I6USV5Ulc
|
||||||
-> ssh-rsa krWCLQ
|
-> ssh-rsa krWCLQ
|
||||||
2oFukVzQIv5zXfd2pK3XwE8xHLCcV7+oORMdz+pTOry9d0u6VQhP5+aKd26/d9q3
|
MXO3xn7SQrbcha9SUyaujaAQH2GTfdsb2Ec42QC5B+BCiFEte48mHTzMUZXDiOF/
|
||||||
/WL8AszBl9d6czi99QKlliGyjw8K2vl3jOYZCTUJj25bBUsL0wt3Qok26Ywmgg2A
|
00/f4iVLEx8WLRp7YU5Y7ipigGdN+1r3V+ZRLlm7JzoAJ+fFJmqd9ErIzy+trdjC
|
||||||
zTWT4AZqgdoQ886kiZFLEePAhVaJ1OOY4ucPkFynKRigqv4gULzwEQQDogLeY2sk
|
D3LtNsxwBqHAtXsaq42uF5oV08xvqmrfM6t4YywKsaENSWeRIglSY/ZwzyRugrTr
|
||||||
FuhJQlK6nhjakro4rfQxWVnciuPUK0kV0ULGZXrxN/vrpK9zV1CdBnjgjtehMfRA
|
DmMHnL9PTYr0cnF1vb7hbbN+l01NfCc7MaLKLWA5i3kzuhzKAx48RhCf3eay/6/r
|
||||||
qzf9FxMyxS/5RV+oCeFWS0jeEOoLun2lwUH8/rGlMeyU1Jq23q07bozWsUitcM2E
|
t4bcEAuvj24gaB0bU6Lom65PH/FL69bBtjrFWrPPQIbX88+z+md+nb8++k9NSTD7
|
||||||
IfFMhX2QT/WzmSraBIzs7g
|
PeavB+zvA+PkXJMiTpVO8Q
|
||||||
-> ssh-ed25519 /vwQcQ OihcemSx1H5D32fB6XReME+z01e5f2wbEsjY4ou7Kgs
|
-> ssh-ed25519 /vwQcQ Uvp34DlCMLtalncf41gr4qJL2tySq52jeM4K1DBPCSY
|
||||||
2zyndfT7gXpYmQzMmgXLx+1L0A6XftTGbDqfjeMAoaU
|
yIJfRyIlZ7ShYdTDgebYriHVySvqvuPZoNKATDceL4k
|
||||||
-> ssh-ed25519 0R97PA OkPY1xsNp3YqSkuo5J+RqjIkBTua9H0CHunZaYvqfQo
|
-> ssh-ed25519 0R97PA pOecxvmM8Xk2T8oEhugDCB152QYs0IPBHyDDrRFbySA
|
||||||
8DFe5TUziFk9rbXa8nodX7rE62mh7DicWCJzEpLn2jE
|
kuJF7YejPboLWTAc1oRIFS6gp/pe7gyuPIfsH49XLNc
|
||||||
-> ssh-rsa jL+Elw
|
-> ssh-rsa jL+Elw
|
||||||
sJTALMXdOMyhtL8DD8Qyq587PQGyH/hTrMQ32pLbYnVwfX6wKvEBR7lyPMN3jLbk
|
Fb0wbIz3bKDqqlzXonleDkfK9CWiXwW5o9LkvVuCIYwq/o0F69Sn0itWeIo1cQ+s
|
||||||
56WhA9X8Op0zOCzJd1DldKZeGMqUK2fYcjv1JrhTlE0LfS7Y3W4zCEadVr6pbkXo
|
fL5QEsRRbTsYZ63O8uJvdr2867wv0pzGffmErXv+rzVZoFMqq2swJ5Mn0yUXzItH
|
||||||
jc98q3RNdD6V4RqrdtndienJ9zM+vQnyxmkVZOl+z+yi/y7ceLUZcbVBChMTh/Ok
|
CPhRoLHfewMZVgE+fti4UigZxiOtoPR1+Nsmn2NcypNaz5Y+3J75zSHDCrcbJr0L
|
||||||
PiS60pk0NA9DFIds+IKVeKGA26iq0s2cjg0AUaicyV1LK4TF3LdLf4aanHt5QWE9
|
/U5ACXMPpFocZcL9CO6lySxJNyaOFyl8sX1azCjSeN3C87OMsRBQ7YO0/UL6FxWp
|
||||||
ykQbtQLpp8DQifBNEl80YBg62YVz8f5B3/zBMjZaxIKIKXsdNTc7bqzbzPIhVUse
|
cwGTcd+sEgrf1bybR9p7khdsbPybpLzFtjcCpXjncdhagPG1241ohWGbCAx9bHtl
|
||||||
C+6Kutx2mskiWtMvYh15kkfbuBnI3wtV98IFLhFaZGRy0NBH3sguQvEUb2tNzyBT
|
mSWhz89RCn6Tf00drosGdLyhKR7JfLr76mFdmU3xmKkZZu6xMkeoXDmUdtOd52ri
|
||||||
F5hUqzXsKlmH4wKYAZV1JNwaEn1UzLx52+1Qq4V1VKimEc/kfTJpwSbWF76LLB0s
|
iF/OcHXFD/G4Vx2Fd8z1sTgIOYP0cDpzcn4JkWK9WjVyg9o4FNz98sfTSKEEcZc3
|
||||||
GVEWd5wpG2KDLKeIxFptPj+HpEAfRTE/MSW/9zz1V7Be1gk4ZFrQikj2LbY+MIvy
|
dQSNpokXW9NH4VFrOkkdUzFn7kE7ZL5QcHmrxKQKS4gJ/Keq/g+WirV9bZ6w0QbQ
|
||||||
Z76xYvZA5RN+dHD+FuAhPzuEP8YpsBKAHiMbbKvwE4cIHuacgK6uiGVxNYEha/dJ
|
75JLS8/LAI8uXHzDYDVggp851eZIOTFL1SchjSjN/6BN+e/H02r9HbxxGnmOjNuw
|
||||||
Met7RrF5kPSs4KrAmdFEq07ebfLoBD4DDbjJ3TDiFrap8kXLsekNNuz2By04TRZv
|
0nC9R6t2nnwElw64TZyZru9VHPGGqWFmuyNOqj53Cn5PGNpy5hEiycMhT+Leh0De
|
||||||
KCZGqR1c9EVGuAU5GgXHYsBcGUHBy5SoEpeuRVrpLz8
|
hv/cQVlfFbZfRK8PMWrsZi0P88AG5XgzeEtnuRPqjqE
|
||||||
-> ssh-ed25519 jIXfPA bUYlIimYWfzWGWlmXx2cvbhFIwqJV/d1VrFvdAIBKw8
|
-> ssh-ed25519 jIXfPA j9rQS9GZYQTZli6ORRchsXBkoknUp7vSKLIAnOP7iD0
|
||||||
pyb/vVXXcY3NuVWwRF9QTLQUUvXbKXU4TY6FU7nBanE
|
nwrzn2WAkFVYNn9l7BgDdwgB52Fg0yF3zVKZfdgJXAw
|
||||||
-> ssh-ed25519 um7xWA DX1EN7dexMvKKuf69E2rnWtQDRXBMf5d5/l1ej/DPhQ
|
-> ssh-ed25519 um7xWA /uvTBZxHjZwq8y/hpfKtZE91IXlPpw9lrwP05lzsC3o
|
||||||
8qeFNTNnBfArNGwEIqlbmuWQz9T4oJhjdzScoyPeyyc
|
kSqDREa/Sd4PHHsEnr49Vlis1bP/baFiRR8Adx4QvZw
|
||||||
--- GqybhtQAk+XPOg90zmdeUUOSmT/cHs5RLgxnif8gTNM
|
--- 3t77fHsF25pYb0OuVHB4FlJQp8nPq2rD7wbNK4dzqcE
|
||||||
àØ—¤Î-<½‚ÎÝ”X Œ?à(Œ'aUI_xCòRpOjCêgj§r³Ýµ ‡^Âç_…>6H~´ŒV§f—)…9â@eô×ÖÈ=|}\½TÅŸ34‰îÄ0'Mï¹<C3AF>”"Ü»<C39C>ï¶À(k«¼àîúVÜLFâéUƒS‹’A£tÔ“ysSQø£,’Oó²r]Iª•ô‹·ÐÒÉ,}À¾nö!êõõó€Ûÿveþ}ct&÷ÿÕ€ö)¸ðü¹r½!¯ø;Unqu¼ÌÝÇwᢵã.vºã^ˆÖX¬Íª¨Öú9w ±åìqŸ<71>Úg.ò6É!1Aäãñ°©åØ€°>0§§üo•–‚µ2Àð”ŠòôT5<Ÿ>ÄÓâp~g9¨#ûuZ%ÒÕ@ãžà÷\läZ«¥Ÿhbý
|
(§ÞÊRQµ@“âÕ6_:§<><]|o‰Ú<E280B0>¼ßhiy<{Ì,·a B›±Í~›oÿ÷ðê«ÝèÍžrI½<>—†ß;ƒêK¹1Óä3RîÓî2¯Ä©…7YçËk®<6B>>ªŽ–”¦¶“‹Ñ/„Áýõý÷P9ã_ݺ ê6c.Û®ù›Å>b;ýªn1~7i%Û‰wBä6{|>tŽ”˜¦{úcDù¬e‚±ÉÅG±q«ÍÁOö``Ø¿{Ë&Vˆ‹’]ÍYæ”ï[òµVŽC/JM 7s7<73>ËþÞotb<74>¥¨úàP¸‘×¥<XâÊ”åÔ<C3A5>hã¨Ô2DÓ›ØÆÍÖékë[µ¬lÝ<6C>ëðFV)ƒ¬×ž{8([C«§² îxŸPZï$@ï_¡T1fÙrú@…üª›Ø¹žAkÅ#–ážE p6¯d=r»ƒQ8Ü)Ø‚<C398>OžÞ™q€<71> gjaà{VVD|‹r¯æº<C3A6>èî,°<>pûï£,Ç’{·§ò^(£¥Ú[Ü<lÁÎI|Ä^Êá²£ï<C2A3>H‹w+YFÔÇ^Vá'\
|
||||||
sÚð<C39A>n$hR%F™mÛPÅ„”V²‡óI¤²F»%yÃw¬öl¤0Gø×Ë)Éç3ÅM
|
wƒ¸ôo랓ƣ»–²&¸óƒ‡÷
|
||||||
0„•:ÊÁ*Žq„1ÈßÔ˜½”Ðçq'øYÔGâä_i(“ìk •œÝq[&,]œ‰·™ovzùä1öû<19>vv
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue