From 36478eb5075612d2dbddb076920747a14b707594 Mon Sep 17 00:00:00 2001 From: dvirlabs <114520947+dvirlabs@users.noreply.github.com> Date: Wed, 4 Jun 2025 00:36:06 +0300 Subject: [PATCH] Fix pull from minio --- backend/.env | 4 +++ backend/__pycache__/main.cpython-312.pyc | Bin 0 -> 4296 bytes backend/apps.yaml | 10 +++--- backend/main.py | 33 ++++++++++-------- frontend/src/components/AppCard.jsx | 42 +++++++++++++++-------- frontend/src/services/api.js | 4 +-- frontend/vite.config.js | 1 + 7 files changed, 58 insertions(+), 36 deletions(-) create mode 100644 backend/.env create mode 100644 backend/__pycache__/main.cpython-312.pyc diff --git a/backend/.env b/backend/.env new file mode 100644 index 0000000..901386b --- /dev/null +++ b/backend/.env @@ -0,0 +1,4 @@ +MINIO_ACCESS_KEY=TDJvsBmbkpUXpCw5M7LA +MINIO_SECRET_KEY=n9scR7W0MZy6FF0bznV98fSgXpdebIQjqZvEr1Yu +MINIO_ENDPOINT=s3.dvirlabs.com +MINIO_BUCKET=navix-icons \ No newline at end of file diff --git a/backend/__pycache__/main.cpython-312.pyc b/backend/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d8011592cf8c3cde3b3553ce33edd5ca69b4a52 GIT binary patch literal 4296 zcmb6cTWl29_1<~x&hE~>ytda*@PpTqVkeZOQt3NN-FW0&sNPxrT(n5sJIi5A~hfF-vX9s`RX~dJG+i$tL?1k z+;h)8=iYPAoR|L+4EhN?AC4ay`;Cu~zvIMxycOixpE*M2iAq#zkPJ;yia2L*89vE7 zIBy6UF)2E@V0e-qSQia%MoLN*nlI@Cn#b^G0?B|w^BQs{m<&3&WP~!|WZ1!dMkEtW zMk(QlM(c~s3yfgER@2E+-m>RrC%XqQ@ zPF$ZSROM;hkSAQ_iEqdgsq!=dPgrZv8nw6@_%wP?sOZqF)+JluuHSL>tBq>Rl~(Jo z6ZdAxHrOekwYzKM2Wk>7rZ!9k2uW_+66lwbx*5}YFl;ZcCG6Ir*66~RQ2Anfi|0~G9B7hkm+0{vrXHsc3p(8$Xdah z1Y<{X2i$(g_?g<7E~a*?Thy&!+ik9GDVY=|g~axMB1?kW-Xn@>^_@NjXsG|xncv0sT|Ws^{i<}%hNOirmUqahUs!-G;1uUR;Oc{qH4^v zLnn_79Xpj892z)%>e$d(J5rwa_4f}B52sEHo^vU~gZ*a)&pH&j%yand{u6^|6TIzL z(rL{!Qx~;K+iz-cxaHs;z$chC704==^eemcG+g-w?M=Iu#1Rqzxd!jEIshjK#dJVb zPN&1<_xxp=;D>B)1~yklwW;p!YeqVk(K@VLhc%{kRLtC=UidhSyI;FP-v%7G}?+k};;lUc|p~ zO%Jf4r$4(3V4he2%g;Dc*F3H#n}TZ!tCD-jDoK^UhsJ~FRdSVBZcZiRQkl9MP7~Mn z(;WCW{9IW|hDkShg_!g*N69((0N~B!3V)7(@r5B<)ELXLsaW-P9od}KaUnO6Rc*== zqV4NDeR?=`4yRH|7A)*Ivzbac&dgfjM8{?fUC{xU#?3f@pOIyM z@Y=C5h}IW{`emPd{d;8@WMBW{U9hsj#YHfIbMZ+Y5{v|w9L!p5()L0)mv03hZ7AVk zJ+KGsMSvfVy@Fsj0!K>>!&RE^!6|~*;WcFdpm{KI?agIh~6daDt*1mqeI*4A7MBttG<8^@zH+{N7d z;cAL8o!u{x>55Jp?7og(|NoiLGl?HoZA8hs_V#RGZ_Kf4o@qK={W?w;_l?}8dQ}Na z#o7#Z>ks7&wwCVlSMr;0$d)QjZL$tHne7B%3*dZaf^#NpA5!RL+hamdPMEd`-l?ex zKkGz(3?tT!U<-n+2wnwXdteW!CJYmdEvS0hs-!}7B9l)D4CB}KLV0B9Y!A<_r039anf3>j-*V1>G_o8GU3(f1Pz!^L1H0wx>iA1GC=cK;7JHHxDgnzs~$JQw+Sc zEXU@K+&uMA?pl(&7GM2%??-z-KKRkWV)wTn$b0@KM@wE1EBT2pGUs2CS|3VXOH$Wz zee?XuJ13VLTISE)IX8d)&iP`))#q+kci!Yos_`9|Nk^fUyd?3nyE{X#o@8?l* zpxrwa>BX$v`{N6`p<$xEYD+GLj9J-zTX;)=kLFA{|EPv7yO52`X2@2 ziw$@AMfpKsS3%h2WLhjp*yp5DQxcB*z+0!hFZVb<{f*6_3vUZ!In%O*e2!VRhiOg? z-)Va3Ryo8%7%4R+Y!8?W8tSrzF-I~? zE{?5j+1V?VHgxz3wx`_3+B`@&?H(EjeFQ4BCl5_K#HSPM*rk+98`dc_3{-3k%yQ+! z@8Oh0+dFXyz7m7-&nB{KD)^LcgE-P$BQ)jgcE2d3e=SlTag7CoYhwd3@b86qqCDM1O~`hoOq+@ zy{6fnMcPo}8tCS^?>;3kplqWL8f+xP?Cut&rW^8 jH-8ED5yCS^Z=87V#GHSz`F{Op>R*Nal1PLWCsO_c?!l~O literal 0 HcmV?d00001 diff --git a/backend/apps.yaml b/backend/apps.yaml index e29b753..5d815ea 100644 --- a/backend/apps.yaml +++ b/backend/apps.yaml @@ -1,25 +1,25 @@ sections: - apps: - description: Dashboards - icon: http://192.168.10.118:1111/icons/grafana.svg + icon: grafana.svg name: Grafana url: https://grafana.dvirlabs.com - description: Monitoring - icon: http://192.168.10.118:1111/icons/prometheus.svg + icon: prometheus.svg name: Prometheus url: https://prometheus.dvirlabs.com name: Monitoring - apps: - description: Git server - icon: http://192.168.10.118:1111/icons/gitea.svg + icon: gitea.svg name: Gitea url: https://git.dvirlabs.com - description: Container registry - icon: http://192.168.10.118:1111/icons/harbor.svg + icon: harbor.svg name: Harbor url: https://harbor.dvirlabs.com - description: CI/CD - icon: http://192.168.10.118:1111/icons/woodpecker-ci.svg + icon: woodpecker-ci.svg name: Woodpecker url: https://woodpecker.dvirlabs.com name: Dev-tools \ No newline at end of file diff --git a/backend/main.py b/backend/main.py index 2a70f2b..7f6354f 100644 --- a/backend/main.py +++ b/backend/main.py @@ -1,5 +1,8 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +import os +from dotenv import load_dotenv import yaml from pathlib import Path from pydantic import BaseModel @@ -17,12 +20,20 @@ app.add_middleware( allow_headers=["*"], ) +load_dotenv() + +# Load ENV variables +MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT") +MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY") +MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY") +MINIO_BUCKET = os.getenv("MINIO_BUCKET") + # MinIO connection with access and secret keys minio_client = Minio( - "minio.dvirlabs.com", - access_key="YOUR_MINIO_ACCESS_KEY", - secret_key="YOUR_MINIO_SECRET_KEY", - secure=True # Set to False if using HTTP + MINIO_ENDPOINT, + access_key=MINIO_ACCESS_KEY, + secret_key=MINIO_SECRET_KEY, + secure=True ) BUCKET = "navix-icons" @@ -76,16 +87,10 @@ def add_app(entry: AppEntry): return {"status": "added"} @app.get("/icon/{filename}") -def get_presigned_icon_url(filename: str): - try: - url = minio_client.presigned_get_object( - bucket_name=BUCKET, - object_name=filename, - expires=timedelta(hours=1) - ) - return {"url": url} - except Exception as e: - return {"error": str(e)} +def get_public_icon_url(filename: str): + url = f"https://{MINIO_ENDPOINT}/{MINIO_BUCKET}/{filename}" + return JSONResponse(content={"url": url}) + if __name__ == "__main__": diff --git a/frontend/src/components/AppCard.jsx b/frontend/src/components/AppCard.jsx index 4e2fdc6..9fe7f08 100644 --- a/frontend/src/components/AppCard.jsx +++ b/frontend/src/components/AppCard.jsx @@ -1,25 +1,37 @@ import { useEffect, useState } from 'react'; -import { getIconUrl } from '../services/api'; +import '../style/AppCard.css'; +import { getIconUrl } from '../services/api'; function AppCard({ app }) { - const [iconUrl, setIconUrl] = useState(''); + const [iconUrl, setIconUrl] = useState(null); useEffect(() => { - if (app.icon) { - getIconUrl(app.icon) - .then(setIconUrl) - .catch(() => setIconUrl('fallback-icon.svg')); - } - }, [app.icon]); + if (app.icon) { + getIconUrl(app.icon) + .then((url) => { + console.log('Presigned icon URL for', app.name, ':', url); + setIconUrl(url); + }) + .catch((err) => { + console.error(`Failed to load icon for ${app.name}:`, err); + }); + } +}, [app.icon, app.name]); return ( - -
- {app.name} -
-

{app.name}

-

{app.description}

-
+ ); } diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index 31231bb..d9929ed 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -18,5 +18,5 @@ export async function getIconUrl(filename) { const res = await fetch(`/icon/${filename}`); if (!res.ok) throw new Error(`Failed to fetch icon for ${filename}`); const data = await res.json(); - return data.url; -} \ No newline at end of file + return data.url; // ✅ must return the actual URL string +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js index 04886e1..ea8be0a 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -8,6 +8,7 @@ export default defineConfig({ proxy: { '/apps': 'http://localhost:8000', '/add_app': 'http://localhost:8000', + '/icon': 'http://localhost:8000', } } });