diff --git a/.gitignore b/.gitignore index e75fdbd..89cd006 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,16 @@ dmypy.json *.sqlite3 .github .venv + +# Virtual environment +venv/ +.autoenv.zsh +.autoenv_leave.zsh +.autoenv.*.zsh + +# Python cache +__pycache__/ +*.pyc +*.pyo +*.pyd +.Python diff --git a/README.md b/README.md index 9577a63..03706f9 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ - **📚 BookStack Wiki**: Documentation and knowledge base (port 6875) - **🤖 Ollama + Open WebUI**: Local LLM chatbot interface (port 8080) - **📨 Matrix Synapse**: Print order collection and payment tracking (port 8008) -- **🐳 Portainer**: Container management dashboard (port 9000) -- **� JupyterHub**: Multi-user Jupyter notebook server for drone programming (port 8001) +- **� Element Web**: Browser-based Matrix chat client (port 8082) +- **�🐳 Portainer**: Container management dashboard (port 9000) +- **📓 JupyterHub**: Multi-user Jupyter notebook server for drone programming (port 8001) - **🦊 Forgejo**: Self-hosted Git service for code collaboration (port 3003) -- **�🔄 Watchtower**: Automatic container updates every 24 hours +- **🔄 Watchtower**: Automatic container updates every 24 hours --- @@ -126,9 +127,13 @@ graph TB ### Prerequisites +**On the host system:** - **Docker** & **Docker Compose** installed +- **curl** - for testing and healthchecks (install: `brew install curl` on macOS) - **Poppler** (for pdf2image - included in Docker) -- **Port availability**: 80, 3003, 6875, 8001, 8008, 8080, 9000, 11434 +- **Port availability**: 80, 3003, 6875, 8001, 8008, 8080, 8082, 9000, 11434 + +**Note:** Python dependencies are containerized and don't need to be installed on the host. ### Installation @@ -158,8 +163,10 @@ graph TB - Open WebUI: - Portainer: - Matrix: + - Element Web: - JupyterHub: - Forgejo: + - Forgejo: ### First-Time Setup diff --git a/create_room.py b/create_room.py new file mode 100644 index 0000000..8732345 --- /dev/null +++ b/create_room.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +""" +Create a Matrix room for print orders +""" +import json +import requests + +access_token = "syt_ZWluc3p3b3ZpZXI_vebsCCpDYUkfsqLgnvjz_1WOI0g" +user_id = "@einszwovier:124.local" + +# Create room +data = { + "name": "Print Orders", + "topic": "PDF print order submissions from the web app", + "preset": "private_chat", + "visibility": "private" +} + +headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json" +} + +response = requests.post( + "http://localhost:8008/_matrix/client/r0/createRoom", + json=data, + headers=headers +) + +print(f"Room creation response: {response.status_code}") +print(json.dumps(response.json(), indent=2)) + +if response.status_code == 200: + room_id = response.json()['room_id'] + print(f"\n✅ Room created successfully!") + print(f"Room ID: {room_id}") + print(f"\n📋 Add this to your .env file:") + print(f"MATRIX_ROOM={room_id}") +else: + print(f"\n❌ Room creation failed") diff --git a/docker-compose.yml b/docker-compose.yml index dcea9b0..a74d6ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -65,12 +65,7 @@ services: mem_limit: 16g cpus: 6.0 mem_reservation: 4g - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:11434/ || exit 1"] - interval: 60s - timeout: 10s - retries: 3 - start_period: 60s + # Healthcheck removed - ollama image doesn't include curl labels: - "com.centurylinklabs.watchtower.enable=true" - "description=Local LLM inference engine" @@ -179,11 +174,7 @@ services: - WATCHTOWER_INCLUDE_RESTARTING=true - WATCHTOWER_LABEL_ENABLE=true command: --cleanup --interval 86400 --label-enable - healthcheck: - test: ["CMD-SHELL", "pgrep watchtower || exit 1"] - interval: 60s - timeout: 10s - retries: 3 + # Healthcheck removed - watchtower runs as background process, pgrep check unreliable labels: - "description=Watchtower Auto-Update Service" - "maintainer=studio einszwovier" @@ -198,16 +189,7 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer_data:/data - healthcheck: - test: - [ - "CMD-SHELL", - "curl -f http://localhost:9000/api/system/status || exit 1", - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s + # Healthcheck removed - portainer image doesn't include curl labels: - "description=Portainer Container Management UI" - "maintainer=studio einszwovier" @@ -232,16 +214,7 @@ services: cpus: 1.0 depends_on: - web - healthcheck: - test: - [ - "CMD-SHELL", - "curl -f http://localhost:8001/hub/health || curl -f http://localhost:8001/hub/ || exit 1", - ] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s + # Healthcheck removed - jupyterhub custom image doesn't include curl labels: - "com.centurylinklabs.watchtower.enable=true" - "description=JupyterHub for interactive notebooks" @@ -286,12 +259,7 @@ services: mem_limit: 512m cpus: 0.5 mem_reservation: 128m - healthcheck: - test: ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 20s + # Healthcheck removed - element-web image doesn't include curl depends_on: synapse: condition: service_started diff --git a/element-web/README.md b/element-web/README.md index 06c8a5c..675fa0c 100644 --- a/element-web/README.md +++ b/element-web/README.md @@ -4,12 +4,12 @@ Element Web is a browser-based Matrix client that connects to the studio einszwo ## Configuration -The `config.json` file configures Element Web to connect to the local Synapse homeserver at `http://einszwovier.local:8008`. +The `config.json` file configures Element Web to connect to the local Synapse homeserver at `http://124.local:8008`. ### Key Settings - **Homeserver**: Points to local Synapse instance -- **Server name**: `einszwovier.local` +- **Server name**: `124.local` - **Brand**: "studio einszwovier Chat" - **Default language**: German (DE) - **Default theme**: Light mode @@ -17,13 +17,13 @@ The `config.json` file configures Element Web to connect to the local Synapse ho ## Access -- **URL**: `http://einszwovier.local:8082` +- **URL**: `http://124.local:8082` - **No app required**: Works in any modern web browser - **Mobile friendly**: Responsive design works on phones and tablets ## Usage -1. Navigate to `http://einszwovier.local:8082` +1. Navigate to `http://124.local:8082` 2. Click "Sign In" or "Create Account" 3. Use existing Matrix credentials or create a new account 4. Join rooms (e.g., the print order room) @@ -49,7 +49,7 @@ Element Web is managed by Watchtower and updates automatically with the rest of - Ensure Synapse is running: `docker-compose ps synapse` - Check Synapse logs: `docker-compose logs synapse` -- Verify hostname resolution: `ping einszwovier.local` +- Verify hostname resolution: `ping 124.local` **Login fails:** diff --git a/element-web/config.json b/element-web/config.json index 3497c3f..2918eef 100644 --- a/element-web/config.json +++ b/element-web/config.json @@ -1,8 +1,8 @@ { "default_server_config": { "m.homeserver": { - "base_url": "http://einszwovier.local:8008", - "server_name": "einszwovier.local" + "base_url": "http://124.local:8008", + "server_name": "124.local" } }, "brand": "studio einszwovier Chat", @@ -16,11 +16,11 @@ }, "room_directory": { "servers": [ - "einszwovier.local" + "124.local" ] }, "enable_presence_by_hs_url": { - "http://einszwovier.local:8008": true + "http://124.local:8008": true }, "terms_and_conditions_links": [], "privacy_policy_url": null diff --git a/forgejo/data/git/.ssh/authorized_keys b/forgejo/data/git/.ssh/authorized_keys new file mode 100644 index 0000000..e69de29 diff --git a/forgejo/data/gitea/avatars/5fd92c6e32e3102ed23d1a77523c3c2d86d506ee5e86d439e13b98cf2062ba6c b/forgejo/data/gitea/avatars/5fd92c6e32e3102ed23d1a77523c3c2d86d506ee5e86d439e13b98cf2062ba6c new file mode 100644 index 0000000..ded3ed8 Binary files /dev/null and b/forgejo/data/gitea/avatars/5fd92c6e32e3102ed23d1a77523c3c2d86d506ee5e86d439e13b98cf2062ba6c differ diff --git a/forgejo/data/gitea/avatars/aab74637b6c33c04d73a89d1f584f407 b/forgejo/data/gitea/avatars/aab74637b6c33c04d73a89d1f584f407 new file mode 100644 index 0000000..be5d256 Binary files /dev/null and b/forgejo/data/gitea/avatars/aab74637b6c33c04d73a89d1f584f407 differ diff --git a/forgejo/data/gitea/conf/app.ini b/forgejo/data/gitea/conf/app.ini index afecad9..3c53c90 100644 --- a/forgejo/data/gitea/conf/app.ini +++ b/forgejo/data/gitea/conf/app.ini @@ -1,5 +1,8 @@ -APP_NAME = Forgejo: Beyond coding. We forge. +APP_NAME = einszwovier forge RUN_MODE = prod +APP_SLOGAN = +RUN_USER = git +WORK_PATH = /data/gitea [repository] ROOT = /data/git/repositories @@ -13,14 +16,16 @@ TEMP_PATH = /data/gitea/uploads [server] APP_DATA_PATH = /data/gitea -DOMAIN = localhost -SSH_DOMAIN = localhost +DOMAIN = 124.local +SSH_DOMAIN = 124.local HTTP_PORT = 3000 -ROOT_URL = +ROOT_URL = http://124.local:3003/ DISABLE_SSH = false SSH_PORT = 22 SSH_LISTEN_PORT = 22 -LFS_START_SERVER = false +LFS_START_SERVER = true +LFS_JWT_SECRET = hZvHy32wQr50I0x51W9WqQvYqNEfm45PqAoq7KJcw2k +OFFLINE_MODE = true [database] PATH = /data/gitea/gitea.db @@ -30,12 +35,15 @@ NAME = gitea USER = root PASSWD = LOG_SQL = false +SCHEMA = +SSL_MODE = disable [indexer] ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve [session] PROVIDER_CONFIG = /data/gitea/sessions +PROVIDER = file [picture] AVATAR_UPLOAD_PATH = /data/gitea/avatars @@ -50,14 +58,43 @@ LEVEL = info ROOT_PATH = /data/gitea/log [security] -INSTALL_LOCK = false +INSTALL_LOCK = true SECRET_KEY = REVERSE_PROXY_LIMIT = 1 REVERSE_PROXY_TRUSTED_PROXIES = * +INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE3NjI3NzI1NDN9.XRM_LxqMxCNJC4odRqZcNZ-C8LNxCV1pDFGi5ks789s +PASSWORD_HASH_ALGO = pbkdf2_hi [service] DISABLE_REGISTRATION = false REQUIRE_SIGNIN_VIEW = false +REGISTER_EMAIL_CONFIRM = false +ENABLE_NOTIFY_MAIL = false +ALLOW_ONLY_EXTERNAL_REGISTRATION = false +ENABLE_CAPTCHA = true +DEFAULT_KEEP_EMAIL_PRIVATE = false +DEFAULT_ALLOW_CREATE_ORGANIZATION = true +DEFAULT_ENABLE_TIMETRACKING = true +NO_REPLY_ADDRESS = noreply.localhost [lfs] PATH = /data/git/lfs + +[mailer] +ENABLED = false + +[openid] +ENABLE_OPENID_SIGNIN = true +ENABLE_OPENID_SIGNUP = true + +[cron.update_checker] +ENABLED = true + +[repository.pull-request] +DEFAULT_MERGE_STYLE = merge + +[repository.signing] +DEFAULT_TRUST_MODEL = committer + +[oauth2] +JWT_SECRET = DCWJLYmNbdJngkBLfZBNHX9IHBFE1A-Op3EvURtCsU0 diff --git a/forgejo/data/gitea/home/.gitconfig b/forgejo/data/gitea/home/.gitconfig new file mode 100644 index 0000000..ec57bef --- /dev/null +++ b/forgejo/data/gitea/home/.gitconfig @@ -0,0 +1,22 @@ +[diff] + algorithm = histogram +[core] + logallrefupdates = true + quotePath = false + commitGraph = true +[gc] + reflogexpire = 90 + writeCommitGraph = true +[user] + name = Gitea + email = gitea@fake.local +[receive] + advertisePushOptions = true + procReceiveRefs = refs/for +[fetch] + writeCommitGraph = true +[safe] + directory = * +[uploadpack] + allowfilter = true + allowAnySHA1InWant = true diff --git a/forgejo/data/gitea/indexers/issues.bleve/index_meta.json b/forgejo/data/gitea/indexers/issues.bleve/index_meta.json new file mode 100644 index 0000000..5dc3405 --- /dev/null +++ b/forgejo/data/gitea/indexers/issues.bleve/index_meta.json @@ -0,0 +1 @@ +{"storage":"boltdb","index_type":"scorch"} \ No newline at end of file diff --git a/forgejo/data/gitea/indexers/issues.bleve/rupture_meta.json b/forgejo/data/gitea/indexers/issues.bleve/rupture_meta.json new file mode 100644 index 0000000..205c7a4 --- /dev/null +++ b/forgejo/data/gitea/indexers/issues.bleve/rupture_meta.json @@ -0,0 +1 @@ +{"version":4} \ No newline at end of file diff --git a/forgejo/data/gitea/indexers/issues.bleve/store/root.bolt b/forgejo/data/gitea/indexers/issues.bleve/store/root.bolt new file mode 100644 index 0000000..9c67bfa Binary files /dev/null and b/forgejo/data/gitea/indexers/issues.bleve/store/root.bolt differ diff --git a/forgejo/data/gitea/queues/common/000002.ldb b/forgejo/data/gitea/queues/common/000002.ldb new file mode 100644 index 0000000..627b9d0 Binary files /dev/null and b/forgejo/data/gitea/queues/common/000002.ldb differ diff --git a/forgejo/data/gitea/queues/common/CURRENT b/forgejo/data/gitea/queues/common/CURRENT new file mode 100644 index 0000000..cacca75 --- /dev/null +++ b/forgejo/data/gitea/queues/common/CURRENT @@ -0,0 +1 @@ +MANIFEST-000004 diff --git a/forgejo/data/gitea/queues/common/LOCK b/forgejo/data/gitea/queues/common/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/forgejo/data/gitea/queues/common/LOG b/forgejo/data/gitea/queues/common/LOG new file mode 100644 index 0000000..fe93b1e --- /dev/null +++ b/forgejo/data/gitea/queues/common/LOG @@ -0,0 +1,16 @@ +=============== Nov 10, 2025 (CET) =============== +12:02:27.139922 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +12:02:27.141510 db@open opening +12:02:27.141943 version@stat F·[] S·0B[] Sc·[] +12:02:27.142289 db@janitor F·2 G·0 +12:02:27.142333 db@open done T·789.083µs +=============== Nov 10, 2025 (CET) =============== +14:41:11.536178 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed +14:41:11.537691 version@stat F·[] S·0B[] Sc·[] +14:41:11.537733 db@open opening +14:41:11.537879 journal@recovery F·1 +14:41:11.537972 journal@recovery recovering @1 +14:41:11.538886 memdb@flush created L0@2 N·26 S·542B "act..igh,v26":"web..low,v17" +14:41:11.539093 version@stat F·[1] S·542B[542B] Sc·[0.25] +14:41:11.543912 db@janitor F·3 G·0 +14:41:11.543982 db@open done T·6.225416ms diff --git a/forgejo/data/gitea/queues/common/MANIFEST-000004 b/forgejo/data/gitea/queues/common/MANIFEST-000004 new file mode 100644 index 0000000..3431bdd Binary files /dev/null and b/forgejo/data/gitea/queues/common/MANIFEST-000004 differ diff --git a/forgejo/data/gitea/sessions/6/7/671ec6cf26e818fa b/forgejo/data/gitea/sessions/6/7/671ec6cf26e818fa new file mode 100644 index 0000000..724f00c Binary files /dev/null and b/forgejo/data/gitea/sessions/6/7/671ec6cf26e818fa differ diff --git a/mailer.py b/mailer.py index 00e180b..bc5686f 100644 --- a/mailer.py +++ b/mailer.py @@ -11,7 +11,7 @@ async def send_order(pdf_path: str, analysis: dict, room_id: str, name: str, com """ matrix_user = os.environ.get("MATRIX_USER") matrix_pass = os.environ.get("MATRIX_PASS") - homeserver = os.environ.get("MATRIX_HOMESERVER", "http://einszwovier.local:8008") + homeserver = os.environ.get("MATRIX_HOMESERVER", "http://124.local:8008") if not matrix_user or not matrix_pass: raise RuntimeError("Missing MATRIX_USER or MATRIX_PASS in environment") diff --git a/main.py b/main.py index 3f477a3..d2404ea 100644 --- a/main.py +++ b/main.py @@ -14,7 +14,7 @@ from dotenv import load_dotenv load_dotenv() # Get server hostname from environment -SERVER_HOSTNAME = os.environ.get("SERVER_HOSTNAME", "einszwovier.local") +SERVER_HOSTNAME = os.environ.get("SERVER_HOSTNAME", "124.local") BOOKSTACK_PORT = os.environ.get("BOOKSTACK_PORT", "6875") OPENWEBUI_PORT = os.environ.get("OPENWEBUI_PORT", "8080") PORTAINER_PORT = os.environ.get("PORTAINER_PORT", "9000") @@ -162,7 +162,7 @@ def send_order_endpoint( analysis = analyze_pdf(path) # Get Matrix room ID from environment - matrix_room = os.environ.get("MATRIX_ROOM", "!eFWbWEnYsgeIKqyfjw:einszwovier.local") + matrix_room = os.environ.get("MATRIX_ROOM", "!PuLwSlWKNgNKvhhCIr:124.local") try: send_order_sync( diff --git a/matrix/data.backup.einszwovier/homeserver.yaml b/matrix/data.backup.einszwovier/homeserver.yaml new file mode 100644 index 0000000..f614703 --- /dev/null +++ b/matrix/data.backup.einszwovier/homeserver.yaml @@ -0,0 +1,30 @@ +# Configuration file for Synapse. + +server_name: "einszwovier.local" +pid_file: /data/homeserver.pid +listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + resources: + - names: [client, federation] + compress: false +database: + name: sqlite3 + args: + database: /data/homeserver.db + +# Connection and performance settings +max_upload_size: 50M +url_preview_enabled: false + +log_config: "/data/localhost.log.config" +media_store_path: /data/media_store +registration_shared_secret: "D2mw3LqNKe98ga-pYO1l5KbXf^jgx&s5yjq&ipAGjln:AzLag8" +report_stats: false +macaroon_secret_key: "T26aaiHWLHbm+P6fi_8:VXTIn0W_kHH__CQAdhPyaLhBe~OG*_" +form_secret: "k,C38Dw^6b8Y+9-cSQpLb@GPoS*1POr8GDWXsLMKLHEU2+&q-@" +signing_key_path: "/data/localhost.signing.key" +trusted_key_servers: + - server_name: "matrix.org" diff --git a/matrix/data.backup.einszwovier/localhost.log.config b/matrix/data.backup.einszwovier/localhost.log.config new file mode 100644 index 0000000..832f0fa --- /dev/null +++ b/matrix/data.backup.einszwovier/localhost.log.config @@ -0,0 +1,39 @@ +version: 1 + +formatters: + precise: + + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s' + + +handlers: + + + console: + class: logging.StreamHandler + formatter: precise + +loggers: + # This is just here so we can leave `loggers` in the config regardless of whether + # we configure other loggers below (avoid empty yaml dict error). + _placeholder: + level: "INFO" + + + + synapse.storage.SQL: + # beware: increasing this to DEBUG will make synapse log sensitive + # information such as access tokens. + level: INFO + + + + +root: + level: INFO + + + handlers: [console] + + +disable_existing_loggers: false \ No newline at end of file diff --git a/matrix/data.backup.einszwovier/media_store/local_content/SS/TE/HHhwXjCaBwfLYCVGStud b/matrix/data.backup.einszwovier/media_store/local_content/SS/TE/HHhwXjCaBwfLYCVGStud new file mode 100644 index 0000000..ded3ed8 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/SS/TE/HHhwXjCaBwfLYCVGStud differ diff --git a/matrix/data.backup.einszwovier/media_store/local_content/gQ/KN/ZaBFNalOxlkNjWdJWEgr b/matrix/data.backup.einszwovier/media_store/local_content/gQ/KN/ZaBFNalOxlkNjWdJWEgr new file mode 100644 index 0000000..080a119 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/gQ/KN/ZaBFNalOxlkNjWdJWEgr differ diff --git a/matrix/data.backup.einszwovier/media_store/local_content/gQ/sU/FYNGErWOmqPqUUJMEqnc b/matrix/data.backup.einszwovier/media_store/local_content/gQ/sU/FYNGErWOmqPqUUJMEqnc new file mode 100644 index 0000000..9ddebcb Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/gQ/sU/FYNGErWOmqPqUUJMEqnc differ diff --git a/matrix/data.backup.einszwovier/media_store/local_content/nK/Zh/YAsMryaSspHiuwYzZgCt b/matrix/data.backup.einszwovier/media_store/local_content/nK/Zh/YAsMryaSspHiuwYzZgCt new file mode 100644 index 0000000..080a119 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/nK/Zh/YAsMryaSspHiuwYzZgCt differ diff --git a/matrix/data.backup.einszwovier/media_store/local_content/nN/WH/wXhmmMhWIPIOVCBkZzlM b/matrix/data.backup.einszwovier/media_store/local_content/nN/WH/wXhmmMhWIPIOVCBkZzlM new file mode 100644 index 0000000..62e7cd1 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/nN/WH/wXhmmMhWIPIOVCBkZzlM differ diff --git a/matrix/data.backup.einszwovier/media_store/local_content/tz/RM/XhTjAmFHkRROyQnXWAcq b/matrix/data.backup.einszwovier/media_store/local_content/tz/RM/XhTjAmFHkRROyQnXWAcq new file mode 100644 index 0000000..080a119 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/tz/RM/XhTjAmFHkRROyQnXWAcq differ diff --git a/matrix/data.backup.einszwovier/media_store/local_content/vk/oF/xzvoGNkcltOmlboBBbvg b/matrix/data.backup.einszwovier/media_store/local_content/vk/oF/xzvoGNkcltOmlboBBbvg new file mode 100644 index 0000000..3f89e32 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_content/vk/oF/xzvoGNkcltOmlboBBbvg differ diff --git a/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/240-240-image-png-scale b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/240-240-image-png-scale new file mode 100644 index 0000000..cca54ba Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/240-240-image-png-scale differ diff --git a/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/32-32-image-png-crop b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/32-32-image-png-crop new file mode 100644 index 0000000..a21d363 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/32-32-image-png-crop differ diff --git a/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/480-480-image-png-scale b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/480-480-image-png-scale new file mode 100644 index 0000000..bf4e8d6 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/480-480-image-png-scale differ diff --git a/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/500-500-image-png-scale b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/500-500-image-png-scale new file mode 100644 index 0000000..fa5a120 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/500-500-image-png-scale differ diff --git a/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/96-96-image-png-crop b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/96-96-image-png-crop new file mode 100644 index 0000000..c24fe57 Binary files /dev/null and b/matrix/data.backup.einszwovier/media_store/local_thumbnails/SS/TE/HHhwXjCaBwfLYCVGStud/96-96-image-png-crop differ diff --git a/matrix/data/homeserver.yaml b/matrix/data/homeserver.yaml index f614703..b3b0081 100644 --- a/matrix/data/homeserver.yaml +++ b/matrix/data/homeserver.yaml @@ -1,6 +1,6 @@ # Configuration file for Synapse. -server_name: "einszwovier.local" +server_name: "124.local" pid_file: /data/homeserver.pid listeners: - port: 8008 @@ -28,3 +28,10 @@ form_secret: "k,C38Dw^6b8Y+9-cSQpLb@GPoS*1POr8GDWXsLMKLHEU2+&q-@" signing_key_path: "/data/localhost.signing.key" trusted_key_servers: - server_name: "matrix.org" + +# Allow guest access +allow_guest_access: true + +# Enable registration +enable_registration: true +enable_registration_without_verification: true diff --git a/register_user.py b/register_user.py new file mode 100644 index 0000000..a628686 --- /dev/null +++ b/register_user.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +""" +Register a user on Matrix server using shared secret +""" +import hmac +import hashlib +import json +import requests + +# Get nonce +nonce_response = requests.get("http://localhost:8008/_synapse/admin/v1/register") +nonce = nonce_response.json()["nonce"] + +print(f"Got nonce: {nonce[:20]}...") + +# Registration details +username = "einszwovier" +password = "einszwo4" +admin = False +shared_secret = "D2mw3LqNKe98ga-pYO1l5KbXf^jgx&s5yjq&ipAGjln:AzLag8" + +# Generate MAC +mac = hmac.new( + key=shared_secret.encode('utf8'), + digestmod=hashlib.sha1, +) + +mac.update(nonce.encode('utf8')) +mac.update(b"\x00") +mac.update(username.encode('utf8')) +mac.update(b"\x00") +mac.update(password.encode('utf8')) +mac.update(b"\x00") +mac.update(b"notadmin" if not admin else b"admin") + +mac_str = mac.hexdigest() + +# Register user +data = { + "nonce": nonce, + "username": username, + "password": password, + "admin": admin, + "mac": mac_str +} + +response = requests.post( + "http://localhost:8008/_synapse/admin/v1/register", + json=data +) + +print(f"\nRegistration response: {response.status_code}") +print(json.dumps(response.json(), indent=2)) + +if response.status_code == 200: + print(f"\n✅ User registered successfully!") + print(f"User ID: {response.json()['user_id']}") + print(f"Access Token: {response.json()['access_token']}") +else: + print(f"\n❌ Registration failed") diff --git a/setup_matrix.py b/setup_matrix.py new file mode 100644 index 0000000..0288f7d --- /dev/null +++ b/setup_matrix.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +""" +Setup script for Matrix: register user and create room +""" +import asyncio +import os +from nio import AsyncClient, RegisterResponse, RoomCreateResponse + +async def setup_matrix(): + homeserver = "http://124.local:8008" + username = "einszwovier" + password = "einszwo4" + + client = AsyncClient(homeserver) + + print("🔧 Setting up Matrix server...") + print(f" Homeserver: {homeserver}") + print(f" Username: {username}") + + # Register the user + print("\n📝 Registering user...") + response = await client.register( + username=username, + password=password + ) + + if isinstance(response, RegisterResponse): + print(f" ✅ User registered: {response.user_id}") + user_id = response.user_id + else: + print(f" ℹ️ User might already exist, trying to login...") + # Try to login instead + response = await client.login(password) + if response.user_id: + print(f" ✅ Logged in as: {response.user_id}") + user_id = response.user_id + else: + print(f" ❌ Failed: {response}") + await client.close() + return + + # Create a room + print("\n🏠 Creating print orders room...") + response = await client.room_create( + name="Print Orders", + topic="PDF print order submissions from the web app", + is_public=False + ) + + if isinstance(response, RoomCreateResponse): + print(f" ✅ Room created!") + print(f" Room ID: {response.room_id}") + print(f"\n✅ Setup complete!") + print(f"\n📋 Add this to your .env file:") + print(f"MATRIX_ROOM={response.room_id}") + else: + print(f" ❌ Failed to create room: {response}") + + await client.close() + +if __name__ == "__main__": + asyncio.run(setup_matrix()) diff --git a/static/css/style.css b/static/css/style.css index c9514bb..2609501 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -538,6 +538,98 @@ a.link-card:hover, font-size: 0.9rem; } +/* ======================================== + ARCHITECTURE SPOILER + ======================================== */ + +.architecture-spoiler { + margin: 0 auto 1.5rem; + max-width: 1200px; + width: calc(100% - 2rem); + background: #ffffff; + border: 1px solid #dee2e6; + border-radius: 8px; + overflow: hidden; +} + +.architecture-summary { + padding: 0.8rem 1.2rem; + background: #f8f9fa; + color: #2C3E50; + cursor: pointer; + font-size: 0.95rem; + font-weight: 600; + display: flex; + align-items: center; + gap: 0.6rem; + transition: background-color 0.2s ease; + user-select: none; + border-bottom: 1px solid #dee2e6; +} + +.architecture-summary:hover { + background: #e9ecef; +} + +.architecture-summary i { + font-size: 1.1rem; + color: #6c757d; +} + +.architecture-spoiler[open] .architecture-summary { + background: #e9ecef; +} + +.architecture-content { + padding: 1.5rem; + background: #ffffff; + text-align: center; + max-height: 70vh; + overflow-y: auto; +} + +.architecture-image { + width: 100%; + max-width: 100%; + height: auto; + max-height: 60vh; + object-fit: contain; + border-radius: 4px; + transition: opacity 0.2s ease; +} + +.architecture-image:hover { + opacity: 0.95; +} + +.architecture-caption { + margin-top: 1rem; + color: #6c757d; + font-size: 0.9rem; + font-style: italic; +} + +/* Responsive adjustments for mobile */ +@media (max-width: 768px) { + .architecture-spoiler { + width: calc(100% - 1rem); + } + + .architecture-content { + padding: 1rem; + max-height: 50vh; + } + + .architecture-image { + max-height: 45vh; + } + + .architecture-summary { + font-size: 0.85rem; + padding: 0.7rem 1rem; + } +} + /* ======================================== BUTTONS diff --git a/static/images/architecture.png b/static/images/architecture.png new file mode 100644 index 0000000..8b3d9c4 Binary files /dev/null and b/static/images/architecture.png differ diff --git a/templates/landing.html b/templates/landing.html index bcb41bd..0b0bb7b 100644 --- a/templates/landing.html +++ b/templates/landing.html @@ -36,8 +36,6 @@ - - - +
JupyterHub
@@ -117,6 +115,20 @@