Fix pull from minio
This commit is contained in:
parent
fee9d2cce5
commit
36478eb507
4
backend/.env
Normal file
4
backend/.env
Normal file
@ -0,0 +1,4 @@
|
||||
MINIO_ACCESS_KEY=TDJvsBmbkpUXpCw5M7LA
|
||||
MINIO_SECRET_KEY=n9scR7W0MZy6FF0bznV98fSgXpdebIQjqZvEr1Yu
|
||||
MINIO_ENDPOINT=s3.dvirlabs.com
|
||||
MINIO_BUCKET=navix-icons
|
||||
BIN
backend/__pycache__/main.cpython-312.pyc
Normal file
BIN
backend/__pycache__/main.cpython-312.pyc
Normal file
Binary file not shown.
@ -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
|
||||
@ -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__":
|
||||
|
||||
@ -1,25 +1,37 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
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 (
|
||||
<a href={app.url} className="app-card" target="_blank" rel="noreferrer">
|
||||
<div className="app-icon-wrapper">
|
||||
<img src={iconUrl} alt={app.name} className="app-icon" />
|
||||
</div>
|
||||
<h3>{app.name}</h3>
|
||||
<p>{app.description}</p>
|
||||
</a>
|
||||
<div className="app-card-wrapper">
|
||||
<a href={app.url} className="app-card" target="_blank" rel="noreferrer">
|
||||
<div className="app-icon-wrapper">
|
||||
{iconUrl ? (
|
||||
<img src={iconUrl} alt={app.name} className="app-icon" />
|
||||
) : (
|
||||
<span className="icon-placeholder">⚠️</span>
|
||||
)}
|
||||
</div>
|
||||
<h3>{app.name}</h3>
|
||||
<p>{app.description}</p>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
return data.url; // ✅ must return the actual URL string
|
||||
}
|
||||
@ -8,6 +8,7 @@ export default defineConfig({
|
||||
proxy: {
|
||||
'/apps': 'http://localhost:8000',
|
||||
'/add_app': 'http://localhost:8000',
|
||||
'/icon': 'http://localhost:8000',
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user