Compare commits
12 Commits
78303bc77e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e43539d8e0 | |||
| 6dd88bf1aa | |||
| 510959340d | |||
| cc6ae5d606 | |||
| ef69a6ec20 | |||
| c2b7530d20 | |||
| edf273e604 | |||
| e097d19f07 | |||
| 4e988fc15d | |||
| 0512357fd0 | |||
| 8df4d6448d | |||
| 2aff93fb92 |
52
.gitea/workflows/deploy.yml
Normal file
52
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
name: Deploy MinIO Explorer
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
create:
|
||||||
|
tags:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install MinIO Client
|
||||||
|
run: |
|
||||||
|
wget https://dl.min.io/client/mc/release/linux-amd64/mc
|
||||||
|
chmod +x mc
|
||||||
|
sudo mv mc /usr/local/bin/
|
||||||
|
|
||||||
|
- name: Prepare files for production
|
||||||
|
run: |
|
||||||
|
# Créer un dossier temporaire pour les fichiers de production
|
||||||
|
mkdir -p dist
|
||||||
|
|
||||||
|
# Copier style.css et script.js sans modification
|
||||||
|
cp style.css dist/
|
||||||
|
cp script.js dist/
|
||||||
|
|
||||||
|
# Traiter index.html : supprimer la section de développement uniquement
|
||||||
|
# Utiliser sed pour supprimer le contenu entre les marqueurs START_DEV_SECTION et END_DEV_SECTION
|
||||||
|
sed '/<!-- START_DEV_SECTION -->/,/<!-- END_DEV_SECTION -->/d' index.html > dist/index.html
|
||||||
|
|
||||||
|
# Vérifier que les fichiers sont créés
|
||||||
|
ls -la dist/
|
||||||
|
|
||||||
|
- name: Configure MinIO Client
|
||||||
|
run: |
|
||||||
|
mc alias set minio ${{ secrets.MINIO_ENDPOINT }} ${{ secrets.MINIO_ACCESS_KEY }} ${{ secrets.MINIO_SECRET_KEY }}
|
||||||
|
|
||||||
|
- name: Deploy to MinIO
|
||||||
|
run: |
|
||||||
|
# Déployer les fichiers sur le bucket
|
||||||
|
mc cp dist/index.html minio/${{ secrets.MINIO_BUCKET }}/
|
||||||
|
mc cp dist/style.css minio/${{ secrets.MINIO_BUCKET }}/
|
||||||
|
mc cp dist/script.js minio/${{ secrets.MINIO_BUCKET }}/
|
||||||
|
|
||||||
|
# Vérifier le déploiement
|
||||||
|
mc ls minio/${{ secrets.MINIO_BUCKET }}/
|
||||||
|
|
||||||
68
README.md
Normal file
68
README.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# MinIO Explorer
|
||||||
|
|
||||||
|
Application web simple pour explorer les fichiers d'un bucket MinIO, style "Index of" Apache.
|
||||||
|
|
||||||
|
## Fonctionnalités
|
||||||
|
|
||||||
|
- 🌐 **Navigation en lecture seule** dans l'arborescence MinIO
|
||||||
|
- 🔍 **Prévisualisation** des fichiers (images, texte, markdown, PDF, vidéo, audio)
|
||||||
|
- 📋 **Copie des liens directs** vers les ressources
|
||||||
|
- 📱 **Interface responsive** (desktop et mobile)
|
||||||
|
- ⚡ **Auto-configuration** depuis l'URL de déploiement
|
||||||
|
- 🗂️ **Auto-ouverture** des fichiers index.rst
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
/
|
||||||
|
├── index.html # Interface principale
|
||||||
|
├── style.css # Styles responsive type "Index of"
|
||||||
|
├── script.js # Logique de navigation et parsing XML
|
||||||
|
├── CLAUDE.md # preuve de la flemme
|
||||||
|
└── README.md # Ce fichier
|
||||||
|
```
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
### Déploiement
|
||||||
|
|
||||||
|
1. Placez les fichiers à la racine du bucket MinIO
|
||||||
|
2. Configurez le bucket en lecture publique
|
||||||
|
3. Activez CORS sur MinIO
|
||||||
|
4. Accédez via `https://votre-minio.com/votre-bucket/index.html`
|
||||||
|
|
||||||
|
### Mode développement
|
||||||
|
|
||||||
|
L'interface inclut un formulaire pour tester différentes URLs MinIO directement depuis le navigateur.
|
||||||
|
|
||||||
|
## Prérequis MinIO
|
||||||
|
|
||||||
|
- Bucket accessible publiquement en lecture
|
||||||
|
- Configuration CORS appropriée :
|
||||||
|
```
|
||||||
|
Access-Control-Allow-Origin: *
|
||||||
|
Access-Control-Allow-Methods: GET
|
||||||
|
Access-Control-Allow-Headers: *
|
||||||
|
```
|
||||||
|
|
||||||
|
## Types de fichiers supportés
|
||||||
|
|
||||||
|
- **Images** : JPG, PNG, GIF, SVG, WebP...
|
||||||
|
- **Texte/Code** : TXT, JSON, XML, HTML, JS, Python...
|
||||||
|
- **Documentation** : Markdown (.md), reStructuredText (.rst)
|
||||||
|
- **Médias** : PDF, MP4, MP3...
|
||||||
|
|
||||||
|
## Navigation
|
||||||
|
|
||||||
|
- Clic sur dossier → navigation
|
||||||
|
- Clic sur fichier → prévisualisation
|
||||||
|
- Bouton "Copier lien" → lien direct dans le presse-papier
|
||||||
|
- Lien ".." → remontée dans l'arborescence
|
||||||
|
|
||||||
|
## Notes techniques
|
||||||
|
|
||||||
|
- **Frontend only** : HTML/CSS/JavaScript vanilla
|
||||||
|
- **API MinIO** : Appels directs à l'API REST ListBucket
|
||||||
|
- **Pas de serveur** : hébergé statiquement dans le bucket
|
||||||
|
- **Historique navigateur** : navigation avec URL fragments (#/path)
|
||||||
|
|
||||||
11
index.html
11
index.html
@@ -5,6 +5,8 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Index of /</title>
|
<title>Index of /</title>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<!-- Prism.js pour la coloration syntaxique -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="page-container">
|
<div id="page-container">
|
||||||
@@ -12,6 +14,7 @@
|
|||||||
<div id="header">
|
<div id="header">
|
||||||
<h1>Index of <span id="current-path">/</span></h1>
|
<h1>Index of <span id="current-path">/</span></h1>
|
||||||
|
|
||||||
|
<!-- START_DEV_SECTION -->
|
||||||
<!-- Formulaire de développement pour tester différentes URLs -->
|
<!-- Formulaire de développement pour tester différentes URLs -->
|
||||||
<div id="dev-form" class="dev-section">
|
<div id="dev-form" class="dev-section">
|
||||||
<h2>Mode Développement</h2>
|
<h2>Mode Développement</h2>
|
||||||
@@ -21,8 +24,11 @@
|
|||||||
|
|
||||||
<button type="submit">Explorer</button>
|
<button type="submit">Explorer</button>
|
||||||
</form>
|
</form>
|
||||||
<div id="config-info"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- END_DEV_SECTION -->
|
||||||
|
|
||||||
|
<!-- Configuration info - toujours présent même en production -->
|
||||||
|
<div id="config-info"></div>
|
||||||
|
|
||||||
<!-- Section d'erreur -->
|
<!-- Section d'erreur -->
|
||||||
<div id="error-section" class="error" style="display: none;">
|
<div id="error-section" class="error" style="display: none;">
|
||||||
@@ -69,5 +75,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
|
<!-- Prism.js core et langages communs -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
121
style.css
121
style.css
@@ -34,6 +34,23 @@ h1 {
|
|||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Styles pour la navigation breadcrumb dans le titre */
|
||||||
|
.path-segment {
|
||||||
|
color: #0066cc;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: normal;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-segment:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: #004499;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path-segment:active {
|
||||||
|
color: #002266;
|
||||||
|
}
|
||||||
|
|
||||||
/* Section développement */
|
/* Section développement */
|
||||||
.dev-section {
|
.dev-section {
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
@@ -133,6 +150,15 @@ tr:hover {
|
|||||||
background-color: #e6f3ff;
|
background-color: #e6f3ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Lignes cliquables */
|
||||||
|
.clickable-row {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clickable-row:hover {
|
||||||
|
background-color: #e6f3ff !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Liens et dossiers */
|
/* Liens et dossiers */
|
||||||
.folder-link {
|
.folder-link {
|
||||||
color: #0066cc;
|
color: #0066cc;
|
||||||
@@ -157,24 +183,41 @@ tr:hover {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bouton copier lien */
|
/* Boutons d'actions */
|
||||||
.copy-btn {
|
.copy-btn,
|
||||||
|
.open-btn {
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-btn:hover {
|
.copy-btn:hover,
|
||||||
|
.open-btn:hover {
|
||||||
background-color: #e0e0e0;
|
background-color: #e0e0e0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.copy-btn:active {
|
.copy-btn:active,
|
||||||
|
.open-btn:active {
|
||||||
background-color: #d0d0d0;
|
background-color: #d0d0d0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.open-btn {
|
||||||
|
background-color: #007acc;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-btn:hover {
|
||||||
|
background-color: #005999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.open-btn:active {
|
||||||
|
background-color: #004d80;
|
||||||
|
}
|
||||||
|
|
||||||
/* Tailles de fichiers */
|
/* Tailles de fichiers */
|
||||||
.file-size {
|
.file-size {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
@@ -244,8 +287,8 @@ tr:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#content-section {
|
#content-section {
|
||||||
flex: 0 0 25%; /* Tableau prend seulement 25% de la hauteur */
|
flex: none; /* Tableau prend l'espace nécessaire */
|
||||||
overflow-y: auto;
|
overflow-y: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
#files-table {
|
#files-table {
|
||||||
@@ -271,8 +314,8 @@ tr:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#content-section {
|
#content-section {
|
||||||
flex: 0 0 20%; /* Encore moins d'espace pour le tableau sur mobile */
|
flex: none; /* Tableau prend l'espace nécessaire */
|
||||||
overflow-y: auto;
|
overflow-y: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
#files-table {
|
#files-table {
|
||||||
@@ -328,7 +371,6 @@ tr:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.preview-content {
|
.preview-content {
|
||||||
padding: 15px;
|
|
||||||
background-color: white;
|
background-color: white;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -361,7 +403,7 @@ tr:hover {
|
|||||||
|
|
||||||
.preview-content iframe {
|
.preview-content iframe {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 500px;
|
height: 100%;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,6 +441,7 @@ tr:hover {
|
|||||||
.rst-content {
|
.rst-content {
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
margin: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-content h1,
|
.markdown-content h1,
|
||||||
@@ -646,6 +689,58 @@ tr:hover {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Styles pour la coloration syntaxique */
|
||||||
|
.preview-content pre[class*="language-"],
|
||||||
|
.preview-content code[class*="language-"] {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
font-family: "Consolas", "Monaco", "Lucida Console", monospace;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content pre[class*="language-"] {
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content code[class*="language-"] {
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ajustements pour les thèmes Prism */
|
||||||
|
.preview-content .token.comment,
|
||||||
|
.preview-content .token.prolog,
|
||||||
|
.preview-content .token.doctype,
|
||||||
|
.preview-content .token.cdata {
|
||||||
|
color: #6a737d;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content .token.string,
|
||||||
|
.preview-content .token.attr-value {
|
||||||
|
color: #032f62;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content .token.keyword,
|
||||||
|
.preview-content .token.operator {
|
||||||
|
color: #d73a49;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content .token.function,
|
||||||
|
.preview-content .token.class-name {
|
||||||
|
color: #6f42c1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content .token.number,
|
||||||
|
.preview-content .token.boolean {
|
||||||
|
color: #005cc5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-content .token.variable {
|
||||||
|
color: #e36209;
|
||||||
|
}
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
address {
|
address {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
@@ -668,3 +763,9 @@ address {
|
|||||||
.icon-parent::before {
|
.icon-parent::before {
|
||||||
content: "⬆️ ";
|
content: "⬆️ ";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Icônes dynamiques pour les fichiers */
|
||||||
|
.file-icon {
|
||||||
|
margin-right: 0.5em;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user